response
為數據請求響應結果唁情,封裝了URLRequest、時間軸甫匹、請求錯誤信息甸鸟,請求成功的數據
等信息,方便開發(fā)人員取用兵迅。
一抢韭、業(yè)務層獲取響應數據
Alamofire.request(url,method: .post,parameters: nil)
.response{ response in
print("response:\(response)")
}
-
response
方法通過閉包向外傳遞響應數據
1、response-方法
方法實現在ResponseSerialization.swift
文件中恍箭,是對響應結果的封裝刻恭,提供序列化和不序列化請求結果的方法,其實都是對結果的一個處理封裝扯夭,因此都放在該文件是合理的鳍贾。下面看一下默認響應處理:
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
}
- 該方法為
DataRequest
的擴展方法,返回self
交洗,可以繼續(xù)鏈式調用骑科,為方便調用,在Request
類中這種寫法比較常見 - 創(chuàng)建了
DefaultDataResponse
對象构拳,并初始化咆爽,將請求過程中所有參數整合
該方法在序列化文件中,都是對
Request
相關子類的擴展置森,以便于業(yè)務層調用斗埂。前面有講到過,Request
是面向業(yè)務層的暇藏,提供responseJSON蜜笤、downloadProgress、response
等方法盐碱。
DefaultDataResponse
為一個結構體把兔,在Response.swift
文件中,是默認的存儲結構瓮顽。
2县好、Response-結構體
在Response.swift
中聲明了多個結構體,應對不同的使用場景暖混。分類如下:
DefaultDataResponse
DataResponse
DefaultDownloadResponse
DownloadResponse
在業(yè)務層調用的response
中對應的為DefaultDataResponse
結構體缕贡,此處沒有做序列化處理,只是對數據進行整合。業(yè)務層的方法調用和內部結構體的聯系如下:
1晾咪、
response{ response in } -> DefaultDataResponse
只做數據整合
2收擦、responseJSON{ response in } -> DataResponse
對請求數據做序列化處理再整合
3、downloadProgress.response -> DefaultDownloadResponse
整合存儲下載相關信息
4谍倦、downloadProgress.response(responseSerializer) -> DownloadResponse
整合存儲下載相關信息
為什么沒有upload
對應的結構體呢塞赂,因為upload
返回結果就是普通的數據返回,以上提供的方法便可公用昼蛀。
通過Request
對象的一步步調用宴猾,最終數據會處理未Response
的形式,通過閉包調用向業(yè)務層發(fā)送response
類型消息叼旋。
二仇哆、DataResponseSerializer-序列化器
在Request
類中提供了序列化處理和非序列化處理,可以根據需要來調用夫植。下面看一下讹剔,序列化器是如何序列化的。方法入口如下:
Alamofire.request(url,method: .post,parameters: nil).responseJSON {
(response) in
switch response.result{
case .success(let json):
print("json:\(json)")
break
case .failure(let error):
print("error:\(error)")
break
}
}
-
responseJSON
就是獲取一個json
類型的數據偷崩,原始數據在方法內部被序列化過
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
)
}
-
jsonResponseSerializer
實際上是一個函數指針辟拷,供response
內部調用,通過該函數來處理數據
jsonResponseSerializer實現:
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)
}
}
- 實現閉包連接阐斜,共
ResponseSerialization
中的response
方法內部調用
最終調用serializeResponseJSON
方法來序列化數據。代碼如下:
public static func serializeResponseJSON(
options: JSONSerialization.ReadingOptions,
response: HTTPURLResponse?,
data: Data?,
error: Error?)
-> Result<Any>
{
//代碼省略
do {
let json = try JSONSerialization.jsonObject(with: validData, options: options)
return .success(json)
} catch {
return .failure(AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error)))
}
}
- 這里就能看到我們熟悉的身影诀紊,通過
JSONSerialization
對數據做序列化處理 - 根據序列化結構返回
.success
或.failure
以上方法的調用如下:
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
}
- 調用序列化方法谒出,傳入必要參數,對數據序列化處理邻奠,最終返回一個
Result
的枚舉 - 將序列化產生的枚舉
result
封裝至dataResponse
中笤喳,此時序列化到響應就全都完成 - 將結果通過閉包在主隊列中向外發(fā)送
三、Result
是一個枚舉碌宴,在response
中傳遞的既是該枚舉類型的變量杀狡,通過變量來判斷數據請求是成功還是失敗。
.responseJSON { (response) in
switch response.result {
case .success(let json):
print("json:\(json)")
break
case .failure(let error):
print("error:\(error)")
break
}
}
只有json
序列化之后才會有以上枚舉變量贰镣,來通知業(yè)務層序列化成功還是失敗呜象。
四、總結
1碑隆、
response
在序列化器ResponseSerialization
中初始化恭陡;
2、序列化器實際上是Request
類的擴展上煤,方便通過閉包向業(yè)務層傳遞請求結果休玩;
3、序列化器的Request
的擴展方法中都返回self
,以便于鏈式調用拴疤;
4永部、response
幫助我們統(tǒng)一管理請求過程中的數據,請求成功呐矾、失敗苔埋、時間軸等等,便于業(yè)務層處理凫佛;
5讲坎、Response
為不同請求類型,提供不同的結構體類型來管理數據愧薛。