我可以向您建议如何通过使用Alamofire 将Decodable 与您的API 调用结构一起使用。
我创建了继承自SessionManager 的RequestManager 类,并在其中添加了对所有人通用的请求调用。
class RequestManager: SessionManager {
// Create shared instance
static let shared = RequestManager()
// Create http headers
lazy var httpHeaders : HTTPHeaders = {
var httpHeader = HTTPHeaders()
httpHeader["Content-Type"] = "application/json"
httpHeader["Accept"] = "application/json"
return httpHeader
}()
//------------------------------------------------------------------------------
// MARK:-
// MARK:- Request Methods
//------------------------------------------------------------------------------
func responseRequest(_ url: String, method: Alamofire.HTTPMethod, parameter: Parameters? = nil, encoding: ParameterEncoding, header: HTTPHeaders? = nil, completionHandler: @escaping (DefaultDataResponse) -> Void) -> Void {
self.request(url, method: method, parameters: parameter, encoding: encoding, headers: header).response { response in
completionHandler(response)
}
}
}
然后在另一个类创建 NetworkManager 类之后,该类包含所需的 get/post 方法调用并由 JSONDecoder 解码 json,如下所示:
class NetworkManager {
static let shared = NetworkManager()
var progressVC : ProgressVC?
//----------------------------------------------------------------
// MARK:-
// MARK:- Get Request Method
//----------------------------------------------------------------
func getResponse<T: Decodable>(_ url: String, parameter: Parameters? = nil, encoding: ParameterEncoding = URLEncoding.default, header: HTTPHeaders? = nil, showHUD: HUDFlag = .show, message: String? = "Please wait...", decodingType: T.Type, completion: @escaping (Decodable?, APIError?) -> Void) {
DispatchQueue.main.async {
self.showHideHud(showHUD: showHUD, message: "")
}
RequestManager.shared.responseRequest(url, method: .get, parameter: parameter, encoding: encoding, header: header) { response in
DispatchQueue.main.async {
self.showHideHud(showHUD: .hide, message: "")
}
guard let httpResponse = response.response else {
completion(nil, .requestFailed("Request Failed"))
return
}
if httpResponse.statusCode == 200 {
if let data = response.data {
do {
let genericModel = try JSONDecoder().decode(decodingType, from: data)
completion(genericModel, nil)
} catch {
do {
let error = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]
if let message = error!["message"] as? String {
completion(nil, .errorMessage(message)!)
} else if let message = error!["message"] as? Int {
completion(nil, .errorMessage(String(describing: "Bad Request = \(message)")))
}
} catch {
completion(nil, .jsonConversionFailure("JSON Conversion Failure"))
}
}
} else {
completion(nil, .invalidData("Invalid Data"))
}
} else {
completion(nil, .responseUnsuccessful("Response Unsuccessful"))
}
}
}
}
ProgressVC 是我的自定义类,用于在 api 调用时显示进度视图。
之后,我创建了DataManager 类,它将帮助我创建请求 url。
class DataManager: NSObject {
//------------------------------------------------------------------------------
// MARK:- Variables
//------------------------------------------------------------------------------
static let shared = DataManager()
let baseUrl = WebServiceURL.local
//------------------------------------------------------------------------------
// MARK:- Custom Methods
//------------------------------------------------------------------------------
// Get API url with endpoints
func getURL(_ endpoint: WSEndPoints) -> String {
return baseUrl + endpoint.rawValue
}
}
我创建了以下枚举以在我的完成块中发送数据或错误。
enum Result<T, U> where U: Error {
case success(T)
case failure(U)
}
这里是存储与 api 调用期间触发的状态相关的自定义消息的错误列表。
enum APIError: Error {
case errorMessage(String)
case requestFailed(String)
case jsonConversionFailure(String)
case invalidData(String)
case responseUnsuccessful(String)
case jsonParsingFailure(String)
var localizedDescription: String {
switch self {
case.errorMessage(let msg):
return msg
case .requestFailed(let msg):
return msg
case .jsonConversionFailure(let msg):
return msg
case .invalidData(let msg):
return msg
case .responseUnsuccessful(let msg):
return msg
case .jsonParsingFailure(let msg):
return msg
}
}
}
然后,我将扩展这个DataManager 类来调用基于模块的Web 服务。所以我将创建 Swift 文件并扩展 DataManager 类并调用相关 API。
见下文,在 API 调用中,我会将相关模型返回到 Result,如 Result<StoreListModel, APIError>
extension DataManager {
// MARK:- Store List
func getStoreList(completion: @escaping (Result<StoreListModel, APIError>) -> Void) {
NetworkManager.shared.getResponse(getURL(.storeList), parameter: nil, encoding: JSONEncoding.default, header: getHeaders("bd_suvlascentralpos"), showHUD: .show, message: "Please wait...", decodingType: StoreListModel.self) { (decodableData, apiError) in
if apiError != nil {
completion(.failure(apiError!))
} else {
guard let userData = decodableData as? StoreListModel else {
completion(.failure(apiError!))
return
}
completion(.success(userData))
}
}
}
}
从请求的完成块中,我将获得可解码的数据,在这里可以安全地键入 cast。
用途:
DataManager.shared.getStoreList { (result) in
switch result {
case .success(let storeListModel):
if let storeList = storeListModel, storeList.count > 0 {
self.arrStoreList = storeList
self.tblStoreList.isHidden = false
self.labelEmptyData.isHidden = true
self.tblStoreList.reloadData()
} else {
self.tblStoreList.isHidden = true
self.labelEmptyData.isHidden = false
}
break
case .failure(let error):
print(error.localizedDescription)
break
}
}
注意:-一些变量,模型类是我自定义的。你可以用你的替换它。