• 自定义 Alamofire 的 response serializer


    Alamofire 的 DataRequest 类针对二进制数据、字符串、json、属性列表提供了一系列方便解析的方法(内部实际上使用的是 Response Serializer),现在我们要针对服务端返回的数据格式定义我们自己的 Response Serializer。

    假设服务器返回的数据格式是这样的:

    {
        "code": 0,
        "datas": {
            "name": "Jack",
            "age": 13
        },
        "message": ""
    }
    

    其中 datas、message 对应的数据可能为空,我们来针对这个格式定义 Response Serializer。

    从二进制数据到数据模型,直接使用 Swift 4 内置的 JSONDecoder 进行解析,所以,定义的模型需要遵从 Decodable 协议(下面的代码,我为了偷懒直接写了 Codable)。

    struct Response<T: Codable>: Codable {
        let code: Int
        let datas: T?
        let message: String?
    }
    
    struct Person: Codable {
        let name: String
        let age: Int
    }
    
    extension DataRequest {
        static func customResponseSerializer<T: Codable>(type: T.Type) -> DataResponseSerializer<T> {
            return DataResponseSerializer(serializeResponse: { (request, response, data, error) -> Result<T> in
                guard error == nil else {
                    return .failure(error!)
                }
                let result = Request.serializeResponseData(response: response, data: data, error: nil)
                switch result {
                case .success(let validData):
                    do {
                        let entity = try JSONDecoder().decode(T.self, from: validData)
                        return .success(entity)
                    } catch {
                        return .failure(error)
                    }
                case .failure(let error):
                    return .failure(error)
                }
            })
        }
    
        @discardableResult
        func responseCustomObject<T: Codable>(queue: DispatchQueue? = nil,
                                    type: T.Type,
                                    completion: @escaping (DataResponse<T>) -> Void) -> Self {
            return response(queue: queue, responseSerializer: Alamofire.DataRequest.customResponseSerializer(type: type), completionHandler: completion)
        }
    }
    

    使用的时候,这样就好了:

    Alamofire.request("http://mall.cnrmall.com/api/app/version_check").responseCustomObject(type: Response<VersionInfo>.self) { (response) in
        switch response.result {
        case .success(let value):
            print(value)
        case .failure(let error):
            print("error: (error.localizedDescription)")
        }
    }
    
  • 相关阅读:
    使用线程加载指定目录下的所有子目录和文件名称到TreeView中
    《C++代码设计与重用》读后感
    无限分类编辑移动栏目代码
    查询数据库中所有记录总数不为0的数据表名称
    DES,RC2,Rijndael, TripleDes,RSA, MD5, SHA1通用的安全密码类
    SQL过滤掉空格和其他特殊字符函数
    @property详解:nonatomic,retain (转)
    UITextField控件处理键盘弹出时遮住输入框的问题
    iphone 定时器的使用
    苹果官方例子代码
  • 原文地址:https://www.cnblogs.com/xjshi/p/10683979.html
Copyright © 2020-2023  润新知