Alamofire 执行同步请求
更新于:2022-02-21 标签:AlamofireSwift

网络编程时,当业务逻辑变得复杂,难免会遇到回调嵌套。Javascriptasync/await异步处理方案让我们不再受callback回调噩梦的困扰。

本文介绍一种让Alamofire实现类似于async/await的同步请求方案,优雅摆脱回调地狱。演示如下,基于 Alamofire 5.0+

// 异步请求
AF.request(LOGIN_URL, method: .post, parameters: params).responseDecodable(of: MyNetWorkModel.self) { (response) in
    if response.result == .success { ... }
}
// 同步请求
let response = AF.request(LOGIN_URL, method: .post, parameters: params).responseDecodable(of: MyNetWorkModel.self)
if response.result == .success { ... }

实现

信号量实现等待

简单复习一下信号量,DispatchSemaphore 声明时规定信号量计数的初始值,wait()方法会让信号量值减一,signal()会让信号量值加一。当信号量值为 0 时等待(直到 timeout),否则正常执行。

AlamofireDataRequest类添加extension,用信号量实现完成前等待。

import Alamofire
extension DataRequest {
    public func responseSync<T: DataResponseSerializerProtocol>(responseSerializer: T) -> AFDataResponse<T.SerializedObject> {
        let semaphore = DispatchSemaphore(value: 0)
        var result: AFDataResponse<T.SerializedObject>!
        self.response(queue: DispatchQueue.global(qos: .default), responseSerializer: responseSerializer) { response in
            result = response
            semaphore.signal()
        }
        _ = semaphore.wait(timeout: DispatchTime.distantFuture)
        return result
    }
}

定义同名方法

再根据业务需求定义实现同步的同名方法,调用定义的 responseSync 方法即可,这里以 responseDecodable 方法举例。

public func responseDecodable<T: Decodable>(of type: T.Type = T.self) -> AFDataResponse<T> {
    return self.responseSync(responseSerializer: DecodableResponseSerializer(
        dataPreprocessor: DecodableResponseSerializer<T>.defaultDataPreprocessor,
        decoder: JSONDecoder(),
        emptyResponseCodes: DecodableResponseSerializer<T>.defaultEmptyResponseCodes,
        emptyRequestMethods: DecodableResponseSerializer<T>.defaultEmptyRequestMethods)
    )
}

注意

不能放在主线程中使用。刷新主线程数据时记得加上:

DispatchQueue.main.async { ... }
次元物语

载入中..

-「载入中..」
左邻右舍

• 按部就班填坑

• 天道轮回 斗转星移

• Alive: 0 天 0 小时 0 分

• © 2018-2024 Arabaku

Support:

framessrserverDNS
back2top