我正在用Alamofire 3将这段代码迁移到Alamofire 4。参考资料是:在Swift中用AlamoFire创建泛型方法
我有一节课:
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<_>) -> Void’
我怎么才能修好它?
发布于 2018-04-05 22:33:49
您正在从异步方法返回,并且期望结果是有效的,我认为您应该重新考虑一下sendRequest方法的实现。您可以这样做,它需要完成闭包。
而且,您的BaseUser似乎不是一个模型类,而是一些处理程序类,可以这么说。它只有两个属性是闭包,您试图从http请求映射什么。它应该有一些真实的属性。
有了它,如果您有一个纯模型类和一个正确的发送方法,那么您可以很容易地实现您正在尝试的目标。
在您的情况下,错误是因为您正在使用、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的协议ObjectMapper,那么它应该是很好的。
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。
现在,您可以使用扩展来数组并遵守协议。我们可以在这里使用SWIFT4.1 条件一致性。
extension Array: BaseMappable where Element: BaseMappable {
public mutating func mapping(map: Map) {
var userHolder: [BaseUser] = []
// map array of values to your BaseUser
}
}有了这个你就可以走了。请注意,我向您展示了如何解决您的问题。我还做了一些小的重构,只是为了使代码更加清晰。
请根据您的需要进行更改。
https://stackoverflow.com/questions/49681933
复制相似问题