Я бы предложил сделать следующее:
- Создать базовую службу, как указано ниже
import UIKit
import Foundation
enum MethodType: String {
case get = "GET"
case post = "POST"
case put = "PUT"
case patch = "PATCH"
case delete = "DELETE"
}
class BaseService {
var session: URLSession!
// MARK: Rebuilt Methods
func FireGenericRequest<ResponseModel: Codable>(url: String, methodType: MethodType, headers: [String: String]?, completion: @escaping ((ResponseModel?) -> Void)) {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
// Request Preparation
guard let serviceUrl = URL(string: url) else {
print("Error Building URL Object")
return
}
var request = URLRequest(url: serviceUrl)
request.httpMethod = methodType.rawValue
// Header Preparation
if let header = headers {
for (key, value) in header {
request.setValue(value, forHTTPHeaderField: key)
}
}
// Firing the request
session = URLSession(configuration: URLSessionConfiguration.default)
session.dataTask(with: request) { (data, response, error) in
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
if let data = data {
do {
guard let object = try? JSONDecoder().decode(ResponseModel.self , from: data) else {
print("Error Decoding Response Model Object")
return
}
DispatchQueue.main.async {
completion(object)
}
}
}
}.resume()
}
private func buildGenericParameterFrom<RequestModel: Codable>(model: RequestModel?) -> [String : AnyObject]? {
var object: [String : AnyObject] = [String : AnyObject]()
do {
if let dataFromObject = try? JSONEncoder().encode(model) {
object = try JSONSerialization.jsonObject(with: dataFromObject, options: []) as! [String : AnyObject]
}
} catch (let error) {
print("\nError Encoding Parameter Model Object \n \(error.localizedDescription)\n")
}
return object
}
}
вышеупомянутым классом, вы можете использовать его в других сценариях, добавив объект запроса вэто и прохождение любого класса, который вы хотите, если вы соответствуете протоколу Coddle
Создание модели, соответствующей протоколу Coddle
class ExampleModel: Codable {
var commentId : String?
var content : String?
//if your JSON keys are different than your property name
enum CodingKeys: String, CodingKey {
case commentId = "CommentId"
case content = "Content"
}
}
Создание службы для конкретной модели с подклассами констант конечной точки для BaseService, как показано ниже
class ExampleModelService: BaseService<ExampleModel/* or [ExampleModel]*/> {
func GetExampleModelList(completion: ((ExampleModel?)/* or [ExampleModel]*/ -> Void)?) {
super.FireRequestWithURLSession(url: /* url here */, methodType: /* method type here */, headers: /* headers here */) { (responseModel) in
completion?(responseModel)
}
}
}
class MyLocationsController: UIViewController {
// MARK: Properties
// better to have in base class for the controller
var exampleModelService: ExampleModelService = ExampleModelService()
// MARK: Life Cycle Methods
override func viewDidLoad() {
super.viewDidLoad()
exampleModelService.GetExampleModelList(completion: { [weak self] (response) in
// model available here
})
}
}