You need to enable JavaScript to run this app. 如何将Alamofire完成回调转换为Swift 5.5的Async/Await异步实现
优惠活动
大模型
产品
解决方案
定价
更多

如何将Alamofire完成回调转换为Swift 5.5的Async/Await异步实现

Swift 回调式函数转换为async/await实现方案

原有尝试写法的问题

你写的getTokenBalances3没有输出的核心原因有2个:

  • 你封装的Task内部没有定义返回值,最终拿到的result1是Void类型,print自然没有内容
  • JSON解析是同步操作,不需要额外封装Task执行,直接在当前异步上下文运行即可
  • 强制解包URL和response.data存在崩溃风险,没有兼容错误场景

标准改造实现(完全对齐原有回调函数逻辑)

原来的回调函数返回布尔值标识是否成功,对应改造后的代码如下:

func getTokenBalances() async -> Bool {
    guard let url = URL(string: "someApiUrlFromLostandFound") else {
        print("Invalid URL")
        return false
    }
    // 通过withCheckedContinuation桥接回调和async上下文
    return await withCheckedContinuation { continuation in
        AF.request(url, method: .get).validate().responseData { response in
            do {
                guard let data = response.data else {
                    print("Response Error:", response.error as Any)
                    // 回调返回false对应continuation返回false
                    continuation.resume(returning: false)
                    return
                }
                let apiJsonData = try JSONDecoder().decode(TokenBalanceClassAModel.self, from: data)
                DispatchQueue.main.async {
                    self.getTokenBalancesModel = apiJsonData.data.items
                    // 成功场景返回true
                    continuation.resume(returning: true)
                }
            } catch {
                print("ERROR:", error)
                continuation.resume(returning: false)
            }
        }
    }
}

调用的时候直接用let success = await getTokenBalances()即可拿到执行结果。

更推荐的抛错版实现

如果不需要兼容原有布尔返回值的逻辑,更建议用CheckedThrowingContinuation把错误向上抛出,调用侧可以灵活处理不同异常场景:

// 自定义错误类型
enum TokenBalanceError: Error {
    case invalidUrl
    case responseError(Error?)
    case decodeError(Error)
}

func getTokenBalances() async throws -> [TokenBalanceItem] { // 替换为你items的实际类型
    guard let url = URL(string: "someApiUrlFromLostandFound") else {
        throw TokenBalanceError.invalidUrl
    }
    return try await withCheckedThrowingContinuation { continuation in
        AF.request(url, method: .get).validate().responseData { response in
            switch response.result {
            case .success(let data):
                do {
                    let apiJsonData = try JSONDecoder().decode(TokenBalanceClassAModel.self, from: data)
                    let items = apiJsonData.data.items
                    DispatchQueue.main.async {
                        self.getTokenBalancesModel = items
                        continuation.resume(returning: items)
                    }
                } catch {
                    continuation.resume(throwing: TokenBalanceError.decodeError(error))
                }
            case .failure(let error):
                continuation.resume(throwing: TokenBalanceError.responseError(error))
            }
        }
    }
}

调用时用do-catch捕获错误即可:

do {
    let balances = try await getTokenBalances()
    print(balances)
} catch {
    print("请求失败:", error)
}

你自行实现的getSupportedChains优化建议

你自己写的版本已经可以正常运行,只需修改2点即可更安全:

  • 不要强制解包URL和apiRequest.data,增加校验逻辑
  • 可以替换为withCheckedThrowingContinuation把错误抛出,避免内部吞掉错误

内容的提问来源于stack exchange,提问作者Arturo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 03:48:04