You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift中如何在MVVM架构下封装Alamofire为Async?

如何将Alamofire封装为Async/Await风格

之前我尝试把Alamofire封装成Async/Await风格的时候,找了不少方案都没解决问题,折腾了一阵终于搞定了,把可行的实现方式分享给同样遇到这个问题的开发者。

核心封装实现

我们可以借助Swift的withCheckedThrowingContinuation,把Alamofire的闭包回调转换成Async/Await风格。下面是一个通用的网络工具类封装:

import Alamofire

struct NetworkManager {
    static let shared = NetworkManager()
    
    private init() {}
    
    /// Async/Await风格的GET请求,自动解析Decodable模型
    func get<T: Decodable>(url: String, parameters: Parameters? = nil, headers: HTTPHeaders? = nil) async throws -> T {
        return try await withCheckedThrowingContinuation { continuation in
            AF.request(url, method: .get, parameters: parameters, headers: headers)
                .validate() // 自动验证200-299状态码
                .responseDecodable(of: T.self) { response in
                    switch response.result {
                    case .success(let decodedModel):
                        continuation.resume(returning: decodedModel)
                    case .failure(let requestError):
                        continuation.resume(throwing: requestError)
                    }
                }
        }
    }
    
    /// Async/Await风格的POST请求,自动解析Decodable模型
    func post<T: Decodable>(url: String, parameters: Parameters? = nil, headers: HTTPHeaders? = nil) async throws -> T {
        return try await withCheckedThrowingContinuation { continuation in
            AF.request(url, method: .post, parameters: parameters, headers: headers)
                .validate()
                .responseDecodable(of: T.self) { response in
                    switch response.result {
                    case .success(let decodedModel):
                        continuation.resume(returning: decodedModel)
                    case .failure(let requestError):
                        continuation.resume(throwing: requestError)
                    }
                }
        }
    }
}

实际使用示例

先定义要解析的模型,然后在Task中发起请求:

// 示例模型,需遵循Decodable协议
struct User: Decodable {
    let id: Int
    let username: String
    let email: String
}

// 发起请求的代码
Task {
    do {
        let user: User = try await NetworkManager.shared.get(url: "https://your-api-domain.com/users/1")
        print("获取到用户:\(user.username)")
    } catch {
        print("请求失败:\(error.localizedDescription)")
    }
}

额外说明

  • 这个封装要求项目基于Swift 5.5+,支持Async/Await的系统版本(iOS 15+/macOS 12+/tvOS 15+/watchOS 8+)。
  • 如果需要自定义状态码验证逻辑,可以修改validate()的参数,比如validate(statusCode: 200..<300),或者移除这个方法自己处理响应状态。
  • 如果需要获取响应头、状态码等额外信息,可以自定义一个包含这些数据的结构体,在回调中把它返回给continuation,而不是只返回解析后的模型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:50:41