Alamofire-Response

response.png

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

一、業務層獲取響應數據

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,可以繼續鏈式調用,爲方便調用,在Request類中這種寫法比較常見
  • 創建了DefaultDataResponse對象,並初始化,將請求過程中所有參數整合

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

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

2、Response-結構體

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

DefaultDataResponse
DataResponse
DefaultDownloadResponse
DownloadResponse

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

1、response{ response in } -> DefaultDataResponse 只做數據整合
2、responseJSON{ response in } -> DataResponse 對請求數據做序列化處理再整合
3、downloadProgress.response -> DefaultDownloadResponse 整合存儲下載相關信息
4、downloadProgress.response(responseSerializer) -> DownloadResponse 整合存儲下載相關信息

爲什麼沒有upload對應的結構體呢,因爲upload返回結果就是普通的數據返回,以上提供的方法便可公用。

通過Request對象的一步步調用,最終數據會處理未Response的形式,通過閉包調用向業務層發送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中,此時序列化到響應就全都完成
  • 將結果通過閉包在主隊列中向外發送

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

四、總結

1、response在序列化器ResponseSerialization中初始化;
2、序列化器實際上是Request類的擴展,方便通過閉包向業務層傳遞請求結果;
3、序列化器的Request的擴展方法中都返回self,以便於鏈式調用;
4、response幫助我們統一管理請求過程中的數據,請求成功、失敗、時間軸等等,便於業務層處理;
5、Response爲不同請求類型,提供不同的結構體類型來管理數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章