Alamofire-Response

response爲數據請求響應結果,封裝了URLRequest、時間軸、請求錯誤信息,請求成功的數據等信息,方便開發人員取用。json

1、業務層獲取響應數據

Alamofire.request(url,method: .post,parameters: nil)
    .response{ response in
    print("response:\(response)")
}
複製代碼
  • response方法經過閉包向外傳遞響應數據

一、response-方法

方法實如今ResponseSerialization.swift文件中,是對響應結果的封裝,提供序列化和不序列化請求結果的方法,其實都是對結果的一個處理封裝,所以都放在該文件是合理的。下面看一下默認響應處理: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,能夠繼續鏈式調用,爲方便調用,在Request類中這種寫法比較常見
  • 建立了DefaultDataResponse對象,並初始化,將請求過程當中全部參數整合

該方法在序列化文件中,都是對Request相關子類的擴展,以便於業務層調用。前面有講到過,Request是面向業務層的,提供responseJSON、downloadProgress、response等方法。api

DefaultDataResponse爲一個結構體,在Response.swift文件中,是默認的存儲結構。閉包

二、Response-結構體

Response.swift中聲明瞭多個結構體,應對不一樣的使用場景。分類以下:async

DefaultDataResponse
DataResponse
DefaultDownloadResponse
DownloadResponse
複製代碼

在業務層調用的response中對應的爲DefaultDataResponse結構體,此處沒有作序列化處理,只是對數據進行整合。業務層的方法調用和內部結構體的聯繫以下:函數

一、response{ response in } -> DefaultDataResponse 只作數據整合 二、responseJSON{ response in } -> DataResponse 對請求數據作序列化處理再整合 三、downloadProgress.response -> DefaultDownloadResponse 整合存儲下載相關信息 四、downloadProgress.response(responseSerializer) -> DownloadResponse 整合存儲下載相關信息post

爲何沒有upload對應的結構體呢,由於upload返回結果就是普通的數據返回,以上提供的方法即可公用。ui

經過Request對象的一步步調用,最終數據會處理未Response的形式,經過閉包調用向業務層發送response類型消息。url

2、DataResponseSerializer-序列化器

Request類中提供了序列化處理和非序列化處理,能夠根據須要來調用。下面看一下,序列化器是如何序列化的。方法入口以下:spa

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中,此時序列化到響應就全都完成
  • 將結果經過閉包在主隊列中向外發送

3、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序列化以後纔會有以上枚舉變量,來通知業務層序列化成功仍是失敗。

4、總結

  • 一、response在序列化器ResponseSerialization中初始化;
  • 二、序列化器其實是Request類的擴展,方便經過閉包向業務層傳遞請求結果;
  • 三、序列化器的Request的擴展方法中都返回self,以便於鏈式調用;
  • 四、response幫助咱們統一管理請求過程當中的數據,請求成功、失敗、時間軸等等,便於業務層處理;
  • 五、Response爲不一樣請求類型,提供不一樣的結構體類型來管理數據。
本站公眾號
   歡迎關注本站公眾號,獲取更多信息