Alamofire學習 - Response

前言

在前面幾篇內容中已經大體介紹了AlamofireRequest請求,當一個Request完成的時候,下一步 確定要處理服務器返回的響應數據。本篇內容就記錄一下學習處理響應數據Response的內容。json

Response

先來一個簡單的代碼例子🌰看一下下:swift

SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .response { (response) in
                debugPrint(response)
        }
複製代碼

咱們都知道Alamofire可使用鏈式訪問,那就搞點事作😏,把requestresponse換一下,先進行response,再進行request,換了以後會發現根本不可能😞。這就說明了request必需要在response以前訪問,這也提現了request的重要性安全

好了,在皮一下以後,回到代碼來看,看一下這個response是怎麼實現的:bash

這裏能夠看到 response的任務是加入到了 delegate.queue.addOperation,這個 delegate.queue就是在發起 request以後,建立的 TaskDelegate會默認初始化一個掛起隊列。(具體請看上篇 時間軸部分)而後在 request請求 Complete以後再取消隊列的掛起,保證了隊列中的任務所有是在 request請求完成以後進行的, 這一樣也更加說明了request必需要在response以前訪問。

而後任務被交給了主隊列(畢竟開發者有可能利用response進行UI的更新),能夠看到在這裏並無對response進行序列化,而是初始化了一個DefaultDataResponse類的對象,服務器

DefaultDataResponse是用來保存self.requestself.responseself.delegate.dataself.delegate.errorself.timelineself.delegate.metrics 屬性,並把初始化的DefaultDataResponse對象返回給completionHandler 閉包。(有點相似於Model,通常來講,在swift中,若是隻是爲了保存數據,那麼應該把這個類設計成structstruct是值傳遞,所以對數據的操做更安全。除了定義須要保存的數據屬性後,必須設計一個符合要求的構造函數。), 閉包

小總結:app

  • request(該響應來源於那個請求)
  • response(服務器返回的響應)
  • data(響應數據)
  • error(在請求中可能發生的錯誤)
  • timeline(請求的時間軸封裝)
  • _metrics(包含了請求和響應的統計信息)

這些數據都不是由response來建立的,它只有使用權。也就是說response只是一個數據的保存信息者,把各類數據化零爲整返回給用戶。函數

Response序列化

Alamofire中把Request分爲了4類:post

  • DataRequest
  • DownloadRequest
  • UploadRequest
  • StreamRequest

由於有四種不一樣的Request類型,StreamRequest咱們先a按下不表,對於UploadRequest來講,服務器響應的數據比較簡單,就響應一個結果就行,所以不須要對它的Response專門進行封裝。所以,Alamofire設計了2種與之相對應的Response類型學習

  • DefaultDataResponse / DataResponse
  • DefaultDownloadResponse / DataResponse

細心的你必定會發如今DataRequest 的擴展的中會有兩個response方法,(第一個response方法在上面👆已經給出,下面👇貼出第二個response

在這個序列化的 response方法內部,能夠看到會先進行一個 serializeResponse的操做獲得一個結果 result,而後在初始化一個 DataResponse對象用來保存 self.requestself.responseself.delegate.dataresultself.timelineself.delegate.metrics這些數據,並把 DataResponse對象返回給 completionHandler 閉包。

若是你對比這兩個response方法,聰明而優秀的你就會發現這兩個方法的不一樣之處:

request請求完成以後,獲取到的是沒有通過序列化後的數據,若是調用了沒有序列化的response方法,DefaultDataResponse/DefaultDownloadResponse。若是調用了序列化的response方法,須要傳入一個泛型的responseSerializer 參數,返回的就是DataResponse

能夠看到這個序列化的 response方法遵循了 DataResponseSerializerProtocol協議,下面經過源碼看一下這個協議的具體實現:
在這個協議內部有一個序列化函數 serializeResponse,並返回一個類型爲 SerializedObject的Result,那麼也就是說序列者只須要遵循這個協議就能夠了:因此就有了這樣一個用序列化函數 serializeResponse做爲參數來初始化,而且保存序列化函數的 DataResponseSerializer類;

從這裏咱們知道調用序列化函數serializeResponse會返回一個Result,並且在前面也已經說過,在序列化的response方法內部,看到會先進行一個serializeResponse的操做獲得一個結果result

能夠看到關於 Result的結果只有兩種:成功和失敗。成功就把序列化完成的數據返回,失敗就返回一個 error信息。

Response擴展

若是我想把請求的結果序列化成json類型或者String類型的,怎麼辦,難道調用序列化的response方法拿到返回的內容以後,用戶此時再去本身作序列化成json類型或者String類型的內容?怎麼可能,霸氣側漏的Alamofire早就已經都作好了。

SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .response { (response) in
               
        }
SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .responseData { (responsedata) in
              
        }
SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .responseString { (responseString) in
                
        }
SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .responseJSON { (responsejson) in
                
        }
SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .responsePropertyList{ (responselist) in
                
        }
複製代碼

responseData

responseData在其方法內部是直接調用了 response的序列化方法,那麼也就是和 response同樣,把數據序列化爲 Data類型也就是 Result

這裏傳入的序列化器responseSerializer的參數是DataRequest.dataResponseSerializer(),下面來看一下dataResponseSerializer()

返回的就是 DataResponseSerializer 類型的序列化器, DataResponseSerializer這個類前面已經介紹過,它是用來保存序列化函數的,關鍵在於 Request.serializeResponseData

這裏會根據序列化的成功和失敗來返回數據,返回 .success(validData)或者 .failure(error信息)

註解:emptyDataStatusCodes

若是 HTTP response code204或者 205,就表示 Datanil.

關於responseStringresponseJSONresponsePropertyList在內部是如何實現的,在這裏就不一一列出來了,基本和responseData的套路同樣,有興趣的大佬能夠藉助源碼去看一下。

總結

實際上這個response並非咱們常見的那種response,它只是一個保存內容的載體,它把requestresponsedataerrortimeline_metrics 這些數據所有收集整合起來,放到本身身上,而後一塊兒返回給用戶,這樣用戶在外面能夠拿到他想要的任何數據,這是多麼牛X的處理方式。

相關文章
相關標籤/搜索