Alamofire-Response解析

上几篇介绍了AlamofireSessionManager,SessionDelegate,Request等等。请求之后,必然会响应。那就是我们本篇要讲解的Response,它是什么?

一、Response的设计

Alamofire常规使用:

        SessionManager.default
            .request(urlString)
            .response { (response) in
                print(response)
            }

我们知道Alamofire采用链式设计,那它是如何保证responserequest请求完成后执行的呢?

 public func response(queue: DispatchQueue? = nil, completionHandler: @escaping (DefaultDataResponse) -> Void) -> Self {
        delegate.queue.addOperation {
            (queue ?? DispatchQueue.main).async {
                var dataResponse = DefaultDataResponse(
                    request: self.request,
                    response: self.response,
                    data: self.delegate.data,
                    error: self.delegate.error,
                    timeline: self.timeline
                )

                dataResponse.add(self.delegate.metrics)

                completionHandler(dataResponse)
            }
        }
        return self
    }

response的执行放到队列queue

 self.queue = {
            let operationQueue = OperationQueue()

            operationQueue.maxConcurrentOperationCount = 1
            operationQueue.isSuspended = true
            operationQueue.qualityOfService = .utility

            return operationQueue
        }()
  • 创建操作队列operationQueue
  • operationQueue.maxConcurrentOperationCount = 1串行队列
  • operationQueue.isSuspended = true默认挂起
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let taskDidCompleteWithError = taskDidCompleteWithError {
            taskDidCompleteWithError(session, task, error)
        } else {
        
              //此处省略......

            queue.isSuspended = false
        }
    }
  • queue.isSuspended = false 请求完成的代理让队列执行.
  • 这样就可以保证request执行完成后才执行response

二、Response是什么?

response 分为四种:

  • DefaultDataResponse
  • DataResponse
  • DefaultDownloadResponse
  • DownloadResponse
    我们会有疑惑,downloadupload一般都是成对的,为什么之力没有upload?因为upload返回的只是普通的数据.
   var dataResponse = DefaultDataResponse(
                    request: self.request,
                    response: self.response,
                    data: self.delegate.data,
                    error: self.delegate.error,
                    timeline: self.timeline
                )
                dataResponse.add(self.delegate.metrics)
                completionHandler(dataResponse)
 public init(
        request: URLRequest?,
        response: HTTPURLResponse?,
        data: Data?,
        error: Error?,
        timeline: Timeline = Timeline(),
        metrics: AnyObject? = nil)
    {
        self.request = request
        self.response = response
        self.data = data
        self.error = error
        self.timeline = timeline
    }
  • DefaultDataResponse是结构体
  • 从初始化方法可以看出DefaultDataResponse只是一个信息的保存者
  • 传递到外界供用户使用
  • 面向对象原则
    dataResponse创建时的参数dataerror从哪里来的?
    override var data: Data? {
        if dataStream != nil {
            return nil
        } else {
            return mutableData
        }
    }

data其实是mutableData

  func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        if initialResponseTime == nil { initialResponseTime = CFAbsoluteTimeGetCurrent() }

        if let dataTaskDidReceiveData = dataTaskDidReceiveData {
            dataTaskDidReceiveData(session, dataTask, data)
        } else {
            if let dataStream = dataStream {
                dataStream(data)
            } else {
                mutableData.append(data)
            }

            let bytesReceived = Int64(data.count)
            totalBytesReceived += bytesReceived
            let totalBytesExpected = dataTask.response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown

            progress.totalUnitCount = totalBytesExpected
            progress.completedUnitCount = totalBytesReceived

            if let progressHandler = progressHandler {
                progressHandler.queue.async { progressHandler.closure(self.progress) }
            }
        }
    }

是在代理方法didReceive data放进去的。
error是在didCompleteWithError保存的。

  func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let taskDidCompleteWithError = taskDidCompleteWithError {
            taskDidCompleteWithError(session, task, error)
        } else {
            if let error = error {
                if self.error == nil { self.error = error }

                if
                    let downloadDelegate = self as? DownloadTaskDelegate,
                    let resumeData = (error as NSError).userInfo[NSURLSessionDownloadTaskResumeData] as? Data
                {
                    downloadDelegate.resumeData = resumeData
                }
            }

            queue.isSuspended = false
        }
    }

三、序列化器responseSerializer

这里我们就看看DefaultDataResponseDataResponse的区别
1、DefaultDataResponse.

 public func response(queue: DispatchQueue? = nil, completionHandler: @escaping (DefaultDataResponse) -> Void) -> Self {
        delegate.queue.addOperation {
            (queue ?? DispatchQueue.main).async {
                var dataResponse = DefaultDataResponse(
                    request: self.request,
                    response: self.response,
                    data: self.delegate.data,
                    error: self.delegate.error,
                    timeline: self.timeline
                )

                dataResponse.add(self.delegate.metrics)

                completionHandler(dataResponse)
            }
        }

        return self
    }

DefaultDataResponse初始化方法

public init(
        request: URLRequest?,
        response: HTTPURLResponse?,
        data: Data?,
        error: Error?,
        timeline: Timeline = Timeline(),
        metrics: AnyObject? = nil)
    {
        self.request = request
        self.response = response
        self.data = data
        self.error = error
        self.timeline = timeline
    }

2、DataResponse

   public func response(
        queue: DispatchQueue? = nil,
        responseSerializer: T,
        completionHandler: @escaping (DataResponse) -> Void)
        -> Self
    {
        delegate.queue.addOperation {
            let result = responseSerializer.serializeResponse(
                self.request,
                self.response,
                self.delegate.data,
                self.delegate.error
            )

            var dataResponse = DataResponse(
                request: self.request,
                response: self.response,
                data: self.delegate.data,
                result: result,
                timeline: self.timeline
            )

            dataResponse.add(self.delegate.metrics)

            (queue ?? DispatchQueue.main).async { completionHandler(dataResponse) }
        }

        return self
    }

DataResponse初始化方法

 public init(
        request: URLRequest?,
        response: HTTPURLResponse?,
        data: Data?,
        result: Result,
        timeline: Timeline = Timeline())
    {
        self.request = request
        self.response = response
        self.data = data
        self.result = result
        self.timeline = timeline
    }
  • DefaultDataResponse,默认序列化。没指定序列化器,会返回默认的。
  • 返回DataResponse,如果用户指定序列化器,就会返回序列化处理后的DataResponse
  • DataResponse会包含Result类型的result,序列化后的数据

我们就用json序列化器讲解一下:

        SessionManager.default
            .request(urlString)
            .responseJSON { (jsonResponse) in
                print(jsonResponse)
        }

responseJSON的实现:

public func responseJSON(
    queue: DispatchQueue? = nil,
    options: JSONSerialization.ReadingOptions = .allowFragments,
    completionHandler: @escaping (DataResponse) -> Void)
    -> Self
{
    return response(
        queue: queue,
        responseSerializer: DataRequest.jsonResponseSerializer(options: options),
        completionHandler: completionHandler
    )
}
  • 封装并返回了一个 response
  • DataRequest.jsonResponseSerializer(options: options),序列的初始化
public static func jsonResponseSerializer(
    options: JSONSerialization.ReadingOptions = .allowFragments)
    -> DataResponseSerializer
{
    return DataResponseSerializer { _, response, data, error in
        return Request.serializeResponseJSON(options: options, response: response, data: data, error: error)
    }
}
  • 这里返回 DataResponseSerializer 类型的序列化器,参数是一个闭包,
    其中参数就是一个闭包,保存在DataResponseSerializerserializeResponse
 public static func serializeResponseJSON(
        options: JSONSerialization.ReadingOptions,
        response: HTTPURLResponse?,
        data: Data?,
        error: Error?)
        -> Result
    {
        guard error == nil else { return .failure(error!) }

        if let response = response, emptyDataStatusCodes.contains(response.statusCode) { return .success(NSNull()) }

        guard let validData = data, validData.count > 0 else {
            return .failure(AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength))
        }

        do {
            let json = try JSONSerialization.jsonObject(with: validData, options: options)
            return .success(json)
        } catch {
            return .failure(AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error)))
        }
    }
  • 闭包带有一个返回值类型 Result:Request.serializeResponseJSON
 let result = responseSerializer.serializeResponse(
                self.request,
                self.response,
                self.delegate.data,
                self.delegate.error
            )

response中直接调用responseSerializer.serializeResponse初始化器,获得Result

 public static func serializeResponseJSON(
        options: JSONSerialization.ReadingOptions,
        response: HTTPURLResponse?,
        data: Data?,
        error: Error?)
        -> Result
    {
        guard error == nil else { return .failure(error!) }

        if let response = response, emptyDataStatusCodes.contains(response.statusCode) { return .success(NSNull()) }

        guard let validData = data, validData.count > 0 else {
            return .failure(AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength))
        }

        do {
            let json = try JSONSerialization.jsonObject(with: validData, options: options)
            return .success(json)
        } catch {
            return .failure(AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error)))
        }
    }
  • json序列化器: JSONSerialization.jsonObject
  • 根据序列化的结果返回 : .success(json) 或者 .failure(error)

四、总结

    1. 使用.responseJSON序列化器
    1. 创建序列化器
  • 3.将response添加到操作队列
  • 4.当请求完成后,队列开始执行,
  • 5.调用序列化器执行后返回result
  • 6.response回调返回response响应数据

你可能感兴趣的:(Alamofire-Response解析)