一.默認(rèn)Response
-DefaultDataResponse
- 返回二進(jìn)制數(shù)據(jù)
Data
鲫惶,響應(yīng)示例:
SessionManager.default.request(urlString).response { (response) in
print("\(response)")
}
- 查看源碼:
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
}
- 在這里將
self.request
,self.response
,self.delegate.data
,self.delegate.error
,self.timeline
,整合成DefaultDataResponse
對象,同時(shí)將dataResponse
交給了DispatchQueue.main
主隊(duì)列回調(diào)出去寸潦,方便用戶在請求回調(diào)中處理UI事件。 - 很明顯您市,
DefaultDataResponse
傳遞到外面的是原始的二進(jìn)制數(shù)據(jù),
class DataTaskDelegate: TaskDelegate, URLSessionDataDelegate {
var dataTask: URLSessionDataTask { return task as! URLSessionDataTask }
override var data: Data? {
if dataStream != nil {
return nil
} else {
return mutableData
}
}
- 那么這些數(shù)據(jù)什么時(shí)候賦值的?
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 {
//處理數(shù)據(jù)
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) }
}
}
}
- 在
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
方法瓶珊,收到數(shù)據(jù)的時(shí)候鹅士,就將mutableData.append(data)
追加到了mutableData
中,然后通過response
中的completionHandler(dataResponse)
回調(diào)給用戶轰胁。 - 至于
error
的傳遞和賦值谒主,同上查找方法可知,在收到錯(cuò)誤的時(shí)候赃阀,賦值self.error
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if let taskDidCompleteWithError = taskDidCompleteWithError {
taskDidCompleteWithError(session, task, error)
} else {
if let error = 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
}
}
通過上面的分析霎肯,可能會(huì)有疑問,這么強(qiáng)大的框架榛斯,只是原封不動(dòng)的把二進(jìn)制數(shù)據(jù)傳出來观游,會(huì)不會(huì)有點(diǎn)
low
? 查看其他的response
可知,Alamofire
還有針對響應(yīng)數(shù)據(jù)的序列化操作
二. DataResponse
1. 自定義序列化器
- 此處自定義了
responseSerializer
序列化器驮俗,返回序列化后的數(shù)據(jù)Result<value>
SessionManager.default.request(urlString).response(responseSerializer: DataResponseSerializer<String>.init(serializeResponse: { (reques, response, data, error) -> Result<String> in
print("原始數(shù)據(jù):\(String(describing: response ?? nil))")
return .success("請求數(shù)據(jù)成功")
})) { (dataResponse) in
print("\(dataResponse)")
}
SessionManager.default.request(urlString).response { (response) in
print("\(response)")
}
- 源碼分析:
public func response<T: DataResponseSerializerProtocol>(
queue: DispatchQueue? = nil,
responseSerializer: T,
completionHandler: @escaping (DataResponse<T.SerializedObject>) -> Void)
-> Self
{
delegate.queue.addOperation {
let result = responseSerializer.serializeResponse(
self.request,
self.response,
self.delegate.data,
self.delegate.error
)
var dataResponse = DataResponse<T.SerializedObject>(
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
}
- 首先序列化數(shù)據(jù)懂缕,
let result = responseSerializer.serializeResponse
,返回Result<Value>
類型,通過局部變量result
保存:
public struct DataResponseSerializer<Value>: DataResponseSerializerProtocol {
public typealias SerializedObject = Value
public var serializeResponse: (URLRequest?, HTTPURLResponse?, Data?, Error?) -> Result<Value>
public init(serializeResponse: @escaping (URLRequest?, HTTPURLResponse?, Data?, Error?) -> Result<Value>) {
self.serializeResponse = serializeResponse
}
}
- 調(diào)用
DataResponse
整合數(shù)據(jù)王凑,返回?cái)?shù)據(jù)多了一個(gè)result
搪柑,這個(gè)就是我們序列化后的數(shù)據(jù),然后將數(shù)據(jù)回調(diào)到主線程索烹。由于我們自定義了序列化器工碾,所以在外部序列化的時(shí)候,我們可以對返回的數(shù)據(jù)進(jìn)行預(yù)處理百姓,以滿足我們的需求渊额。
2.自帶responseJSON
SessionManager.default
.request(urlString)
.response { (response) in
print(response)
}.responseJSON { (jsonResponse) in
print(jsonResponse)
}
- 源碼分析:
public func responseJSON(
queue: DispatchQueue? = nil,
options: JSONSerialization.ReadingOptions = .allowFragments,
completionHandler: @escaping (DataResponse<Any>) -> Void)
-> Self
{
return response(
queue: queue,
responseSerializer: DataRequest.jsonResponseSerializer(options: options),
completionHandler: completionHandler
)
}
-
responseSerializer
傳入DataRequest.jsonResponseSerializer(options: options)
序列化參數(shù)
public static func jsonResponseSerializer(
options: JSONSerialization.ReadingOptions = .allowFragments)
-> DataResponseSerializer<Any>
{
return DataResponseSerializer { _, response, data, error in
return Request.serializeResponseJSON(options: options, response: response, data: data, error: error)
}
}
- 繼續(xù)
Request.serializeResponseJSON
public static func serializeResponseJSON(
options: JSONSerialization.ReadingOptions,
response: HTTPURLResponse?,
data: Data?,
error: Error?)
-> Result<Any>
{
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)))
}
}
- 有木有發(fā)現(xiàn),我們自定義的序列化器和系統(tǒng)實(shí)現(xiàn)的
serializeResponseJSON
序列化如出一轍。本質(zhì)上都是傳入一個(gè)序列化參數(shù)旬迹,對數(shù)據(jù)進(jìn)行處理火惊。
三.DefaultDownloadResponse
和 DownloadResponse
DefaultDownloadResponse
public func response(
queue: DispatchQueue? = nil,
completionHandler: @escaping (DefaultDownloadResponse) -> Void)
-> Self
{
delegate.queue.addOperation {
(queue ?? DispatchQueue.main).async {
var downloadResponse = DefaultDownloadResponse(
request: self.request,
response: self.response,
temporaryURL: self.downloadDelegate.temporaryURL,
destinationURL: self.downloadDelegate.destinationURL,
resumeData: self.downloadDelegate.resumeData,
error: self.downloadDelegate.error,
timeline: self.timeline
)
downloadResponse.add(self.delegate.metrics)
completionHandler(downloadResponse)
}
}
return self
}
DownloadResponse
public func response<T: DownloadResponseSerializerProtocol>(
queue: DispatchQueue? = nil,
responseSerializer: T,
completionHandler: @escaping (DownloadResponse<T.SerializedObject>) -> Void)
-> Self
{
delegate.queue.addOperation {
let result = responseSerializer.serializeResponse(
self.request,
self.response,
self.downloadDelegate.fileURL,
self.downloadDelegate.error
)
var downloadResponse = DownloadResponse<T.SerializedObject>(
request: self.request,
response: self.response,
temporaryURL: self.downloadDelegate.temporaryURL,
destinationURL: self.downloadDelegate.destinationURL,
resumeData: self.downloadDelegate.resumeData,
result: result,
timeline: self.timeline
)
downloadResponse.add(self.delegate.metrics)
(queue ?? DispatchQueue.main).async { completionHandler(downloadResponse) }
}
return self
}
- 序列化
public struct DownloadResponseSerializer<Value>: DownloadResponseSerializerProtocol {
public typealias SerializedObject = Value
public var serializeResponse: (URLRequest?, HTTPURLResponse?, URL?, Error?) -> Result<Value>
public init(serializeResponse: @escaping (URLRequest?, HTTPURLResponse?, URL?, Error?) -> Result<Value>) {
self.serializeResponse = serializeResponse
}
}
DefaultDownloadResponse
和DownloadResponse
,對于序列化的處理與DefaultDataResponse
和DataResponse
大同小異;