使用 Alamofire 和 ObjectMapper 的通用网络调用
Generic network call with Alamofire and ObjectMapper
我正在使用 Alamofire 和 Alamofire Object Mapper 来发出网络请求并将其序列化。我们总是通过以下示例获得相同形状的响应,其中包括结果、isSuccessfull 和消息。
{
"Result": {
"WaitingCount": 0,
"ApprovedCount": 0,
"RejectedCount": 0
},
"IsSuccessfull": true,
"Message": null
}
我创建了一个基础 class 以防止代码与以下代码重复。
struct BaseObjectResponseParser<T:Mappable>: Mappable {
public var item: T?
public var isSuccessful:Bool?
public var message: String?
init?(map: Map){
}
mutating func mapping(map: Map) {
item <- map["Result"]
isSuccessful <- map["IsSuccessfull"]
message <- map["Message"]
}
}
然后,对于每个不同的模型,我都创建了一个模型 class,其中包含以下内容。
class UnitWorkOrdersCount: Mappable {
var waitingCount: Int = 0
var approvedCount: Int = 0
var rejectedCount: Int = 0
required init?(map: Map) {
}
func mapping(map: Map) {
waitingCount <- map["WaitingCount"]
approvedCount <- map["ApprovedCount"]
rejectedCount <- map["RejectedCount"]
}
}
我正在使用以下代码片段从服务器进行网络调用并序列化响应。
typealias HandlerGetUnitWorkOrdersCount = (UnitWorkOrdersCount?, _ message: String?) -> ()
func getUnitWorkOrdersCount(by identifier: Int, handler: @escaping HandlerGetUnitWorkOrdersCount) {
let parameters: Parameters = ["identifier": identifier]
Alamofire.request(URL_GET_UNIT_WORK_ORDER_COUNT, method: .get, parameters: parameters).responseObject { (response: DataResponse<BaseObjectResponseParser<UnitWorkOrdersCount>>) in
switch response.result {
case .success:
if let result = response.result.value {
if result.isSuccessful ?? false {
handler(result.item, nil)
} else {
handler(nil, result.message)
}
}
case .failure(let error):
print(error)
handler(nil, error.localizedDescription)
}
}
}
但是,我有很多网络请求,我的代码与上面的代码重复。我试图使它通用,但我无法成功。如何使 networkRequest 函数和我的完成处理程序通用并防止其重复?
您可以尝试将其设为通用,如下所示,
class MyService {
public static func request<T: Mappable>(_ urlString: String,
method: HTTPMethod,
params: Parameters?,
type: T.Type,
completion: @escaping (T?, String?) -> Void) {
Alamofire.request(urlString, method: method, parameters: params).responseObject { (response: DataResponse<BaseObjectResponseParser<T>>) in
switch response.result {
case .success:
if let result = response.result.value {
if result.isSuccessful ?? false {
completion(result.item, nil)
} else {
completion(nil, result.message)
}
}
case .failure(let error):
completion(nil, error.localizedDescription)
}
}
}
}
用法
MyService.request("urlPathString", method: .get, params: nil,
type: UnitWorkOrdersCount.self) { (unitWork, message) in
if let message = message {
print(message)
return
}
print(unitWork!.waitingCount)
}
我正在使用 Alamofire 和 Alamofire Object Mapper 来发出网络请求并将其序列化。我们总是通过以下示例获得相同形状的响应,其中包括结果、isSuccessfull 和消息。
{
"Result": {
"WaitingCount": 0,
"ApprovedCount": 0,
"RejectedCount": 0
},
"IsSuccessfull": true,
"Message": null
}
我创建了一个基础 class 以防止代码与以下代码重复。
struct BaseObjectResponseParser<T:Mappable>: Mappable {
public var item: T?
public var isSuccessful:Bool?
public var message: String?
init?(map: Map){
}
mutating func mapping(map: Map) {
item <- map["Result"]
isSuccessful <- map["IsSuccessfull"]
message <- map["Message"]
}
}
然后,对于每个不同的模型,我都创建了一个模型 class,其中包含以下内容。
class UnitWorkOrdersCount: Mappable {
var waitingCount: Int = 0
var approvedCount: Int = 0
var rejectedCount: Int = 0
required init?(map: Map) {
}
func mapping(map: Map) {
waitingCount <- map["WaitingCount"]
approvedCount <- map["ApprovedCount"]
rejectedCount <- map["RejectedCount"]
}
}
我正在使用以下代码片段从服务器进行网络调用并序列化响应。
typealias HandlerGetUnitWorkOrdersCount = (UnitWorkOrdersCount?, _ message: String?) -> ()
func getUnitWorkOrdersCount(by identifier: Int, handler: @escaping HandlerGetUnitWorkOrdersCount) {
let parameters: Parameters = ["identifier": identifier]
Alamofire.request(URL_GET_UNIT_WORK_ORDER_COUNT, method: .get, parameters: parameters).responseObject { (response: DataResponse<BaseObjectResponseParser<UnitWorkOrdersCount>>) in
switch response.result {
case .success:
if let result = response.result.value {
if result.isSuccessful ?? false {
handler(result.item, nil)
} else {
handler(nil, result.message)
}
}
case .failure(let error):
print(error)
handler(nil, error.localizedDescription)
}
}
}
但是,我有很多网络请求,我的代码与上面的代码重复。我试图使它通用,但我无法成功。如何使 networkRequest 函数和我的完成处理程序通用并防止其重复?
您可以尝试将其设为通用,如下所示,
class MyService {
public static func request<T: Mappable>(_ urlString: String,
method: HTTPMethod,
params: Parameters?,
type: T.Type,
completion: @escaping (T?, String?) -> Void) {
Alamofire.request(urlString, method: method, parameters: params).responseObject { (response: DataResponse<BaseObjectResponseParser<T>>) in
switch response.result {
case .success:
if let result = response.result.value {
if result.isSuccessful ?? false {
completion(result.item, nil)
} else {
completion(nil, result.message)
}
}
case .failure(let error):
completion(nil, error.localizedDescription)
}
}
}
}
用法
MyService.request("urlPathString", method: .get, params: nil,
type: UnitWorkOrdersCount.self) { (unitWork, message) in
if let message = message {
print(message)
return
}
print(unitWork!.waitingCount)
}