Alamofire 的 Swift 扩展方法返回 SwiftyJSON 结果

Posted

技术标签:

【中文标题】Alamofire 的 Swift 扩展方法返回 SwiftyJSON 结果【英文标题】:Swift extension method for Alamofire to return SwiftyJSON result 【发布时间】:2017-01-23 06:11:19 【问题描述】:

我将一个应用程序从 Swift 2.2 迁移到 3.0,它使用了来自 GitHub 上的 Alamofire-SwiftyJSON 项目的扩展方法。 Alamofire-SwiftyJSON 允许接收来自 Alamofire 网络请求的响应,转换为 SwiftyJSON 实例,如下所示:

Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
    .responseSwiftyJSON( (request, response, json, error) in
        print(json) // json is a SwiftyJSON 'JSON' instance
        print(error)
    )

在撰写此问题时,尚未针对 Swift 3 更新 Alamofire-SwiftyJSON 项目。我正在寻找适用于 Swift 3+ 和 Alamofire 4+ 的 responseSwiftyJSON 扩展方法的等效实现。

【问题讨论】:

【参考方案1】:

扩展方法

此解决方案包含来自 SwiftyJSON readme 的关于使用 Alamofire 的建议。

它基于 ResponseSerialization.swift 中的 Alamofire 包含的类似扩展:

DataRequest.responseJSON(queue:options:completionHandler:) DataRequest.jsonResponseSerializer(options:)

此解决方案适用于 Swift 3 及更高版本。它使用 Alamofire 4.2+ 和 SwiftyJSON 3.1.3+ 进行了测试。

import Alamofire
import SwiftyJSON

extension DataRequest 

    /// Adds a handler to be called once the request has finished.
    ///
    /// - parameter options:           The JSON serialization reading options. Defaults to `.allowFragments`.
    /// - parameter completionHandler: A closure to be executed once the request has finished.
    ///
    /// - returns: The request.
    @discardableResult
    public func responseSwiftyJSON(
        queue: DispatchQueue? = nil,
        options: JSONSerialization.ReadingOptions = .allowFragments,
        completionHandler: @escaping (DataResponse<JSON>) -> Void) -> Self 
            return response(
                queue: queue,
                responseSerializer: DataRequest.swiftyJSONResponseSerializer(options: options),
                completionHandler: completionHandler
            )
    

    /// Creates a response serializer that returns a SwiftyJSON instance result type constructed from the response data using
    /// `JSONSerialization` with the specified reading options.
    ///
    /// - parameter options: The JSON serialization reading options. Defaults to `.allowFragments`.
    ///
    /// - returns: A SwiftyJSON response serializer.
    public static func swiftyJSONResponseSerializer(
        options: JSONSerialization.ReadingOptions = .allowFragments) -> DataResponseSerializer<JSON> 
            return DataResponseSerializer  _, response, data, error in
                let result = Request.serializeResponseJSON(options: options, response: response, data: data, error: error)
                switch result 
                    case .success(let value):
                        return .success(JSON(value))
                    case .failure(let error):
                        return .failure(error)
                
            
    

使用示例:

Alamofire.request("https://httpbin.org/get").validate().responseSwiftyJSON 
        response in

        print("Response: \(response)")

        switch response.result 
            case .success(let json):
                // Use SwiftyJSON instance
                print("JSON: \(json)")

            case .failure(let error):
                // Handle error
                print("Error: \(error)")
        
    

【讨论】:

粗糙但优雅,一旦你了解 Alamofire 正在做什么。如果 queue 为 nil,则在 queue 正在运行的线程或主线程上调用 completionHandler。在 Alamofire 内部的 NSOperationQueue 上调用 responseSerializer。我会在 SWiftyJSON 自述文件中添加对 validate() 的调用。 感谢@user992167 的反馈!我按照您的建议添加了 validate() 方法。

以上是关于Alamofire 的 Swift 扩展方法返回 SwiftyJSON 结果的主要内容,如果未能解决你的问题,请参考以下文章

iOS swift 使用 alamofire 在应用程序和共享扩展程序之间共享 cookie

swift上的Alamofire返回状态代码问题

Alamofire 4、Swift 3:无法返回 StatusCode

Swift 2 - 使用 Alamofire 时函数不返回 Bool

如何将 alamofire 返回 json 解析为 Swift 中的字符串数组?

如何从方法返回 alamofire Http 请求的结果?