跳到主要内容

Alamofire 与第三方网络库

问题

Alamofire 提供了哪些 URLSession 没有的能力?什么时候需要使用第三方网络库?

答案

Alamofire 核心能力

// 基本请求
AF.request("https://api.example.com/users")
.validate(statusCode: 200..<300)
.responseDecodable(of: [User].self) { response in
switch response.result {
case .success(let users):
print(users)
case .failure(let error):
print(error)
}
}

// async/await
let users = try await AF.request("https://api.example.com/users")
.validate()
.serializingDecodable([User].self)
.value

拦截器(RequestInterceptor)

struct AuthInterceptor: RequestInterceptor {
// 适配请求(添加 Token)
func adapt(_ urlRequest: URLRequest, for session: Session,
completion: @escaping (Result<URLRequest, Error>) -> Void) {
var request = urlRequest
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
completion(.success(request))
}

// 重试策略
func retry(_ request: Request, for session: Session, dueTo error: Error,
completion: @escaping (RetryResult) -> Void) {
if let statusCode = request.response?.statusCode, statusCode == 401 {
refreshToken { newToken in
completion(.retry) // 刷新 Token 后重试
}
} else {
completion(.doNotRetry)
}
}
}

Alamofire vs URLSession

URLSessionAlamofire
请求简洁度较多样板代码链式调用
自动重试手动实现RequestInterceptor
Token 刷新手动实现AuthenticationInterceptor
请求验证手动检查.validate()
网络监听NWPathMonitorNetworkReachabilityManager

Moya

// 基于 Alamofire 的更高层封装
enum UserAPI {
case getUser(id: Int)
case createUser(name: String)
}

extension UserAPI: TargetType {
var baseURL: URL { URL(string: "https://api.example.com")! }
var path: String {
switch self {
case .getUser(let id): return "/users/\(id)"
case .createUser: return "/users"
}
}
var method: Moya.Method {
switch self {
case .getUser: return .get
case .createUser: return .post
}
}
// ...
}

常见面试问题

Q1: 什么时候需要 Alamofire?

答案:简单请求用 URLSession 足够。当需要统一的请求拦截(Token / 日志)、自动重试、证书固定、网络状态监听等功能时,Alamofire 可以减少大量样板代码。

Q2: 自己封装网络层 vs 用 Alamofire?

答案:关键在于是否有复杂需求。如果只需要简单的 GET/POST + JSON 解析,自己基于 URLSession + async/await 封装即可。如果需要拦截器、重试、多种认证方式,Alamofire 更成熟稳定。

相关链接