最近工作中遇到一個問題,發現用簡單的AFNetworking封裝,不能滿足需求。一般情況下,所有的請求會指定到一個url,然后所有的請求都用AFNetworking的二次封裝方法。如自己封裝的GET,POST方法.這種封裝方式也能滿足大多數的需求。
我們的情況稍有不同,請求API實際不多,但是都在一個控制器之內。大概是一個POST和若干個GET,具體場景大概是這個樣子。
1、向后台post一個請求,后台會根據情況給我們分配一個服務ID,
2、我們根據該ID,可以使用這個服務。但是服務是有狀態限制和生命周期的,create代表服務已經創建,approve代表已經批准,served代表服務過,cancelled代表服務取消。只有在approve的時候我們才能請求后續的API.其他狀態下不會有正確的信息返回。
3、在后台分配的服務狀態未approve的時候,請求某些API,需要輪詢獲取服務狀態,(因為沒有用socket長連接)我們只能自己主動輪詢請求。
4、服務狀態為approve的時候,可以獲取某些實時狀態信息,實時信息需要輪詢獲取,並且有先后順序。
針對以上要求。我一開始的思路是
網絡層用原來的AFNetworking做的簡單的二次封裝 netManager。然后做下面3中請求
1、netManager 先發送一個post獲取到一個服務id
2、netManeger根據服務id,發送get請求,輪詢請求,直到服務狀態返回的是 approved.才進行下一步的請求。
3、approved的狀態下輪詢請求實時獲取某一個對象的狀態信息。直到得到我們想要的狀態。
一般情況下,請求1很好完成。
請求2,3用定時器+GCD+runloop可以實現。
但是由於所有的網絡請求都有netManager來管理,實際情況下請求1的返回時間比較慢,可能要等8s左右(后台建立服務確實是太耗時了)。
2,3請求用定時器每隔0.5s發一次請求。返回的數據及時在UI上更新。如果網絡好的情況下,一般請求沒有問題。
但是網絡太差的情況下發現由於UI上的動畫太過於依賴網絡請求,就會發現動畫卡主。因為循環請求是同步的,且是在一個線程當中的。就會發現如果有一個請求發生了延遲,后續的就要等待,GCD的同步隊列里會有很多個同樣的任務(每隔0.5s添加一個)。如果前一個請求a發出的情況下網絡阻塞,下一個請求b網絡狀況又變好了。就會發現后台的服務中我們要的實時信息已經變了,假如后台狀態每隔0.5s更新一次,每次+1,最開始是0,因為阻塞我們獲取到的信息,第一次是0,第二次就是5了。
所以我們必須在iOS端做超時處理,和POST的超時處理不同,這個超時時間可能是1s左右,因為如果超時時間還和POST設置為8s,一旦網絡阻塞,就會發現獲取不到實時數據了。
我想的是這樣,如果要用一個netManager,肯定不行了。可以這樣POST請求單獨用一個網絡請求類,GET單獨用一個網絡請求類,分別設置不同的超時時間。
超時之后,由AFNetworking幫我們做錯誤反饋,我們會在failure回調里發現這個isCancelled的狀態。
還有一種方法是用一個定時器,一旦發現超時,主動取消該請求。但是主動取消的接口AFNetworking值給了一個 cancellAll的API.我么的任務是放在一個同步隊列里的,所以這中思路似乎不行。如果二次封裝可以取消指定的某一個URL下的get請求,但是我們由於是輪詢請求,那么每一個請求的URL都一樣,會不會把該請求都取消?
有待驗證。
建議:就設計兩個類網絡請求類,除了超時時間設置不一樣之外,其他的請求配置都一樣。超時時間長的用來做post請求,超時時間短的用來做get請求。