我正在将此代码与Alamofire 3
迁移到Alamofire 4
。
参考是:Creating a generic method with AlamoFire in Swift
我有这个课:
import Foundation
import Alamofire
import AlamofireObjectMapper
import ObjectMapper
class HttpHandler {
static func sendRequest<T:BaseUser>(url: String, parameters: [String: AnyObject]?) -> T {
let res : T
Alamofire.request(url)
.validate()
.responseObject { (response: DataResponse<[T]>) in
switch response.result {
case .Success(let value):
res.valueHandle?(value)
case .Failure(let error):
res.errorHandle?(error)
}
}
return res
}
}
class BaseUser: ResponseObjectSerializable {
var valueHandle : ((BaseUser)->())?
var errorHandle : ((NSError)->())?
required init?(response: HTTPURLResponse, representation: AnyObject) {
}
}
public protocol ResponseObjectSerializable {
init?(response: HTTPURLResponse, representation: AnyObject)
}
但是,我收到此错误:
无法将类型'(DataResponse )->()'的值转换为预期值
参数类型'(DataResponse )->无效'
我该如何解决?
最佳答案
您正在从异步方法返回,并期望结果有效,我认为您应该重新考虑sendRequest
方法的实现。您可以使其完成填充。
而且,您的BaseUser似乎不是模型类,而是某种处理程序类。它只有两个属性,即闭包,您尝试从http请求映射什么。它应该具有一些真实属性。
这样,如果您有一个纯模型类和一个适当的send方法,则可以轻松实现您尝试的目标。
您遇到的错误是因为您使用的是 AlamofireObjectMapper ,并且尝试在未实际实现协议的情况下映射值。
看一下方法的签名,
public func responseObject<T>(queue: DispatchQueue? = default,
keyPath: String? = default,
mapToObject object: T? = default,
context: MapContext? = default,
completionHandler: @escaping(Alamofire.DataResponse<T>) -> Swift.Void) -> Self where T : BaseMappable
在这里,一般参数
T
的类型应为BaseMapper
。如果您遵循 ObjectMapper 的协议Mappable
,那就很好了。class BaseUser: BaseMappable {
func mapping(map: Map) {
// map your actual properties here
// like username, name
}
}
我还对
sendRequest
方法进行了一些更改,以使其不返回值,而是执行请求并在完成后进行回调。static func sendRequest<T:BaseUser>(url: String,
parameters: [String: AnyObject]?,
completion: @escaping ([T], Error?) -> Void) {
Alamofire.request(url)
.validate()
.responseObject { (response: DataResponse<[T]>) in
switch response.result {
case .success(let value):
completion(value, nil)
case .failure(let error):
completion([], error)
}
}
}
该代码看起来不错,但尚无法正常工作。您期望将您的响应映射到
BaseUser
数组,但是AlamofireObjectMapper
期望它的类型为Mappable
。现在,您可以使用扩展来排列并遵守协议。我们可以在这里使用Swift 4.1 Conditional Conformance 。
extension Array: BaseMappable where Element: BaseMappable {
public mutating func mapping(map: Map) {
var userHolder: [BaseUser] = []
// map array of values to your BaseUser
}
}
有了这个,你很好。请注意,我向您展示了如何解决您遇到的问题。我也做了一些小的重构,只是为了使代码更清晰。
请根据您的需要进行更改。
关于ios - 将通用功能从Alamofire 3迁移到Alamofire 4,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49681933/