首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将泛型函数从Alamofire 3迁移到Alamofire 4

将泛型函数从Alamofire 3迁移到Alamofire 4
EN

Stack Overflow用户
提问于 2018-04-05 21:38:41
回答 1查看 663关注 0票数 1

我正在用Alamofire 3将这段代码迁移到Alamofire 4。参考资料是:在Swift中用AlamoFire创建泛型方法

我有一节课:

代码语言:javascript
复制
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’

我怎么才能修好它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-05 22:33:49

您正在从异步方法返回,并且期望结果是有效的,我认为您应该重新考虑一下sendRequest方法的实现。您可以这样做,它需要完成闭包。

而且,您的BaseUser似乎不是一个模型类,而是一些处理程序类,可以这么说。它只有两个属性是闭包,您试图从http请求映射什么。它应该有一些真实的属性。

有了它,如果您有一个纯模型类和一个正确的发送方法,那么您可以很容易地实现您正在尝试的目标。

在您的情况下,错误是因为您正在使用、AlamofireObjectMapper并试图映射值,而没有实际实现协议。

看看这个方法的签名,

代码语言:javascript
复制
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,那么它应该是很好的。

代码语言:javascript
复制
class BaseUser: BaseMappable {

    func mapping(map: Map) {
        // map your actual properties here
        // like username, name
    }
}

我还对您的sendRequest方法做了一些更改,这样,它不会返回值,而是执行请求,并在完成后执行回调。

代码语言:javascript
复制
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 条件一致性

代码语言:javascript
复制
extension Array: BaseMappable where Element: BaseMappable {

    public mutating func mapping(map: Map) {
        var userHolder: [BaseUser] = []
        // map array of values to your BaseUser
    }
}

有了这个你就可以走了。请注意,我向您展示了如何解决您的问题。我还做了一些小的重构,只是为了使代码更加清晰。

请根据您的需要进行更改。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49681933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档