Swift网络访问改为async方式 2023-05-11 周四

2023-05-10  本文已影响0人  松哥888

简介

网络库已经封装了Alamofire,只是结果返回是block形式的(也就是闭包),容易形成回调地狱,所以想改为async/await方式。

/// Alamofire 网络信息封装
public class AFNetRequest: NSObject {
    // MARK: - Lifecycle

    /// 单例实例
    /// AFNetRequest.sharedInstance.就是单例的用法
    /// AFNetRequest().就是普通实例的用法
    public static let sharedInstance = AFNetRequest()
    private override init() {}

    /// GET、POST网络请求
    public func requestData(URLString: String,
                            type: AFMethodType,
                            parameters: [String: Any]? = nil,
                            respondCallback: @escaping (_ responseObject: [String: AnyObject]?, _ 
    error: NSError?) -> Void) {
     /// 具体封装过程省略
    }
}

基本思路

function sleep(ms) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('sleep for ' + ms + ' ms');
        }, ms);
    });
}
    /// 网络访问包装为async方式
    public func asyncRequestData(URLString: String,
                                 type: AFMethodType,
                                 parameters: [String: Any]?) async throws -> [String: AnyObject]?
    {
        try await withUnsafeThrowingContinuation { continuation in

            requestData(URLString: URLString, type: type, parameters: parameters) { responseObject, error in
                if let error = error {
                    continuation.resume(throwing: error)
                } else {
                    continuation.resume(returning: responseObject)
                }
            }
        }
    }

如何使用

    func pagerView(_ pagerView: FSPagerView, didSelectItemAt index: Int) {
        print("Did select item at \(index)")
        let item = banners[index]
        let urlString = item["link"] as! String
        var idd: String?
        if let url = URL(string: urlString), let components = URLComponents(url: url, resolvingAgainstBaseURL: true) {
            if let queryItems = components.queryItems {
                for item in queryItems {
                    if item.name == "id" {
                        idd = item.value
                    }
                }
            }
        }
        let strURL = "https://test.pandabuy.com/gateway/resource/notice/detail"
        let parameter: [String: Any] = [
            "id": idd as! String,
        ]

        /// 这是直接使用block的例子
//        AFNetRequest().requestData(URLString: strURL, type: .get, parameters: parameter) { responseObject, error in
//            if error != nil {
//                print("Error: \(error?.description ?? "")")
//                return
//            }
//
//            if let _ = responseObject {
//                let data = responseObject?["data"]
//
//
//                FlutterBoost.instance().open(
//                    "pandaWeb",
//                    arguments: ["animated": true, "present": false,"data":data!,"type":0,"title":data!["title"]],
//                    completion: { _ in }
//                )
//            }
//        }

        /// 这是使用Task包async函数的例子
        Task {
            do {
                let response = try await AFNetRequest.sharedInstance.asyncRequestData(URLString: strURL, type: .get, parameters: parameter)
                if let data = response?["data"] {
                    FlutterBoost.instance().open(
                        "pandaWeb",
                        arguments: ["animated": true, "present": false, "data": data, "type": 0, "title": data["title"] as Any],
                        completion: { _ in }
                    )
                }
            } catch {
                debugPrint(error)
            }
        }
    }

参考文章

将Alamofire完成处理程序转换为Async/Await | Swift5.5
并发
'async' call in a function that does not support concurrency swift ios Xcode async/await
Swift 5.5之Continuation

上一篇 下一篇

猜你喜欢

热点阅读