Alamofire是很常用的swift网络库,本文将分析Alamofire的链式调用。
对Alamofire
不是很熟悉的朋友,可以先看这篇文章
链式调用例子
extension Int {
func add(_ num: Int) -> Int {
return self + num
}
func minus(_ num: Int) -> Int {
return self - num
}
}
print(1.add(2).minus(3)) // 输出毫无疑问是0
Alamofire例子
一个简单的用Alamofire发起的请求,请求结果回调后将解析数据
Alamofire.request(url).responseJSON { (json) in
// do something
}
可以看到下面两个方法都返回DataRequest
,这是链式调用的前提。
@discardableResult
的作用是取消没有使用返回值 编译器给出的警告。
@discardableResult
public func request(
_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil)
-> DataRequest
{
return SessionManager.default.request(
url,
method: method,
parameters: parameters,
encoding: encoding,
headers: headers
)
}
// extension DataRequest
@discardableResult
public func responseJSON(
queue: DispatchQueue? = nil,
options: JSONSerialization.ReadingOptions = .allowFragments,
completionHandler: @escaping (DataResponse<Any>) -> Void)
-> Self // 这里的Self 就是 DataRequest
{
return response(
queue: queue,
responseSerializer: DataRequest.jsonResponseSerializer(options: options),
completionHandler: completionHandler
)
}
都知道网络请求是一个异步的过程。
请各位思考一个问题,在链式调用中如何等待第一个方法回调结束后再执行第二个方法的操作?
也就是如何等待request()
方法回调后再去执行responsJSON()
方法里的操作?
Alamofire是使用NSOperationQueue
来实现
- 首先在处理request回调的delegate定义了一个队列。
- 这个队列在创建的时候是挂起的,然后不断的往里塞任务:比如responseJSON等。然后等回调完成的时候,再唤醒这个队列,按顺序的执行这些任务。
open let queue: OperationQueue
init(task: URLSessionTask?) {
_task = task
self.queue = {
let operationQueue = OperationQueue()
// 串行队列
operationQueue.maxConcurrentOperationCount = 1
// 将队列挂起
operationQueue.isSuspended = true
operationQueue.qualityOfService = .utility
return operationQueue
}()
}
实践
做一个小demo
NetworkTask().request().responseJSON { (data) in
print("data - \(data)")
}
class NetworkTask {
// 专门处理 请求完成后的回调
private let delegate = NetworkDelegate()
@discardableResult
public func request() -> Self {
print("开始网络请求")
// 模拟网络请求过程 3s
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
print("请求成功")
self.delegate.handleRequest()
}
return self
}
@discardableResult
public func responseJSON(compeletionHandler: @escaping (_ data: String) -> ()) -> Self {
print("response任务加入队列")
delegate.queue.addOperation {
print("response任务开始执行 - 当前线程:\(Thread.current)")
DispatchQueue.main.async {
print("开始执行response任务回调 - 当前线程:\(Thread.current)")
compeletionHandler(self.delegate.data)
}
}
return self
}
}
class NetworkDelegate {
let queue: OperationQueue = {
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
queue.isSuspended = true
return queue
}()
var data = ""
func handleRequest() {
// do something...
data = "数据"
print("处理数据")
// 唤醒队列
queue.isSuspended = false
}
}
执行结果
这个queue
也可以用GCD
实现
let queue: DispatchQueue = {
let queue = DispatchQueue(label: "network.task")
queue.suspend()
return queue
}()
func handleRequest() {
// do something...
data = "数据"
print("处理数据")
// 唤醒队列
queue.resume()
}
@discardableResult
public func responseJSON(compeletionHandler: @escaping (_ data: String) -> ()) -> Self {
print("response任务加入队列")
delegate.queue.async {
print("response任务开始执行 - 当前线程:\(Thread.current)")
DispatchQueue.main.async {
print("开始执行response任务回调 - 当前线程:\(Thread.current)")
compeletionHandler(self.delegate.data)
}
}
return self
}