美文网首页
面向协议的网络请求: Bamboots

面向协议的网络请求: Bamboots

作者: CNKCQ | 来源:发表于2017-11-28 22:45 被阅读103次

    封装 一个面向协议的网络请求

    Bamboots 是基于 Alamofire 的一系列扩展库,这个库 充分的体现了 面向 Protocol 编程在组合设计模式中的应用。

    image.png

    目前我对 network request 的希望是: 传入一个请求体:form,然后给我返回: 成功后的模型对象、失败后的 error 对象

    let form = WeatherForm<RootModel>()
    request(
                form,
                success: { (response) in
                    print(response.data.three_day_forecast.count)   
            }) { (error) in
                    print(error.localizedDescription)
            }
    

    当我们也可以根据需要来处理结果,有时候我们对请求成功后的结果感兴趣,有时候我们需要对请求失败后的 error 做特殊处理:

    func request<T: Codable>(
            _ form: WeatherForm<T>,
            success: ((T) -> Void)? = nil ,
            failure: ((_ error: Error) -> Void)? = nil
            )
    

    如上的接口就能满足我们的需要,我们的 form 提供了所有的请求信息, successfailure 两个闭包就是我们可以根据当前网络请求的需要来进行处理了。当然我们对应的闭包传入 nil 或做缺省处理,这样就会使用我们的默认实现了。然后在默认实现里统一处理相关信息,当然这也是工程的一部分了,需要根据具体项目而定了。让我们看一下 WeatherForm<RootModel>() 这个表单里面携带了我们网络请求的一些条件信息,包括: apimethodheardersparameters, 还有我们需要返回的模型类型RootModel 。这些信息中有些是高频修改的,如 apimethodparameters,对于 apimethod 我们通过 enum 统一管理,对于 parameters 我们则通过属性做map来简化请求参数的赋值, 而对于 hearders 这种修改频率低的我们可以做统一处理,在需要修改时再添加extension实现, 如:

    extension Formable {
        public func headers() -> [String: String] {
            return ["accessToken": "xxx"]
        }
    }
    
    extension Formable where Self: RequestFormable {
        public func headers() -> [String: String] {
            return [
            "accessToken": "xxx", "fileName": "xxx",
            "App-Source": "APP",
            "User-Os": "iOS",
            ]
        }
    }
    
    extension Formable where Self: UploadFormable {
        public func headers() -> [String: String] {
            return ["accessToken": "xxx", "fileName": "xxx"]
        }
    }
    

    这里的 WeatherForm<RootModel>() 继承了 GetForm
    当然以上这些是基于 Bamboots 而封装的。我们的 BambootsSwift 3 时是基于 AlamofireObjectMapper
    的,当然这在 Swift 4 中, 我们取而代之使用的就是 AlamofireCodable, 从命名上就可以看出来,功能是一样的,只是在 Swift 4 中我们有了 Codable 我们就可以祛除ObjectMapper了,也许不久我们直接就可以在 Alamofire 看到相应的实现了,

    image.png
    此图为证。AlamofireCodableAlamofire 的基础上为DataRequest 添加了两个扩展函数:
    /// Adds a handler to be called once the request has finished.
        ///
        /// - Parameters:
        ///   - queue:              The queue on which the completion handler is dispatched.
        ///   - keyPath:            The key path where object mapping should be performed
        ///   - completionHandler:  A closure to be executed once the request has finished and the data has been decoded by JSONDecoder.
        /// - Returns:              The request.
        @discardableResult
        public func responseObject<T: Codable>(queue: DispatchQueue? = nil, keyPath: String? = nil,  completionHandler: @escaping (DataResponse<T>) -> Void) -> Self {
            return response(queue: queue, responseSerializer: DataRequest.ObjectSerializer(keyPath), completionHandler: completionHandler)
        }
    

    通过调用 responseObject 直接在回调中返回含有T对象的DataResponse<T>,而下面这个函数

    /// Adds a handler to be called once the request has finished. T: Codable
        ///
        /// - Parameters:
        ///   - queue:              The queue on which the completion handler is dispatched.
        ///   - keyPath:            The key path where object mapping should be performed
        ///   - completionHandler:  A closure to be executed once the request has finished and the data has been decoded by JSONDecoder.
        /// - Returns:              The request.
        @discardableResult
        public func responseArray<T: Codable>(queue: DispatchQueue? = nil, keyPath: String? = nil, completionHandler: @escaping (DataResponse<[T]>) -> Void) -> Self {
            return response(queue: queue, responseSerializer: DataRequest.ObjectArraySerializer(keyPath), completionHandler: completionHandler)
        }
    

    则提供了对数组的支持。

    相关文章

      网友评论

          本文标题:面向协议的网络请求: Bamboots

          本文链接:https://www.haomeiwen.com/subject/mzvzvxtx.html