随着 iOS 开发的发展,异步编程已经成为日常开发的一项必备技能。在 iOS 中,最常见的异步编程方式是使用 Alamofire 框架。Alamofire 是一个强大的网络请求库,可以轻松实现异步编程。本文将介绍如何使用 async/await 封装 Alamofire,以实现更加优雅的异步编程。
首先,我们用Alamofire的URLRequestConvertible封装我们的数据
import Alamofire
enum Router: URLRequestConvertible {
static let baseURLString = "https://jsonplaceholder.typicode.com"
case getUserByPostID(postID: Int)
case comments
case getUserByID(userID: Int)
var method: Alamofire.HTTPMethod {
switch self {
case .getUserByPostID:
return .get
case .comments:
return .get
case .getUserByID:
return .post
}
}
var path: String {
switch self {
case .comments:
return "/comments"
// get请求,参数拼接在URL上
case .getUserByPostID(postID: let postId):
return "/comments?postId=\(postId)"
case .getUserByID:
return "/posts"
}
}
func asURLRequest() throws -> URLRequest {
let url = URL(string: Router.baseURLString + path)!
var request = URLRequest(url: url)
request.method = method
request.timeoutInterval = 30 //15s超时
switch self {
case .comments:
break
case .getUserByPostID(postID: _):
break
//post 请求,参数加在这里
case .getUserByID(userID: let userID):
let para = ["userID": userID]
request = try JSONParameterEncoder().encode(para, into: request)
}
return request
}
}
上面的函数实现了 Alamofire 的URLRequestConvertible协议。它将返回一个URLRequest 参数
- 接下来,我们扩展一下Alamofire.DataRequest
- 它提供了一种简单的方法来管理HTTP网络请求。它提供了基本的HTTP方法,如GET,PUT,POST,DELETE等,以及一些高级的网络功能,如请求超时,文件上传, 数据解析等
- 我们把具体的网络请求业务代码,封装到一个函数中。这样代码看起来会很简洁
extension Alamofire.DataRequest {
func serializingDecodable<Value: Decodable>(_ type: Value.Type = Value.self) async throws -> Value {
let result = await serializingData().result
switch result {
case .success(let data):
do {
return try JSONDecoder().decode(Value.self, from: data)
} catch let error {
throw error
}
case .failure(let error):
throw error
}
}
}
然后,我们封装一下逻辑层,模拟了3个网络请求,其中包括(无参get, 有参get,无参post )
struct NetWork {
static func getUserInfo() async throws -> [Todo] {
let task = AF.request(Router.comments)
return try await task.serializingDecodable([Todo].self)
}
static func getUserInfoByPostId(_ postID:Int) async throws -> [Todo] {
let task = AF.request(Router.getUserByPostID(postID: postID))
return try await task.serializingDecodable([Todo].self)
}
static func getUserInfoByID(_ userID:Int) async throws -> [String:Int] {
let task = AF.request(Router.getUserByID(userID: userID))
return try await task.serializingDecodable([String:Int].self)
}
}
最后,我们可以使用 async/await 封装的函数来获取网络数据:
Task {
do{
let users1 = try await NetWork.getUserInfo()
print("AllUsersCount: \(users1.count)")
let users2 = try await NetWork.getUserInfoByPostId(3)
print("UserInfoByPostIdCount: \(users2.count)")
let users3 = try await NetWork.getUserInfoByID(1)
print("UserInfoByID: \(users3)")
}catch{
print(error)
}
}
// 打印结果:
// AllUsersCount: 500
// UserInfoByPostIdCount: 5
// UserInfoByID: ["userID": 1, "id": 101]
总结一下,本文介绍了如何使用 async/await 封装 Alamofire,以实现更加优雅的异步网络请求。通过使用 async/await,可以使得网络请求变得更加简洁、优雅,让开发者更加轻松地实现异步编程。