- 全稱是AFNetworking
- 雖然運行效率沒有ASI高,但是使用比ASI簡單
- 是對NSURLConnection和NSURLSession的各自的一層包裝
AFN的內部中的RunLoop
- AFN內部開了一條專門用來訪問網絡請求的線程
- 在這個開線程的方法中,他把方法和
dispatch_once
都用static修飾了下 - 以保證這個方法的安全性以及只開辟一塊內存空間,而且保證他線程不死
- 在這個方法中他會調用另一個
網絡請求入口
的方法
- 在這個入口方法中他會創建一個RunLoop
- 然后添加一個
NSMachPort
端口,目的是為了讓他里面有Source(因為有了Source的RunLoop才能真正跑起來) - 然后啟動RunLoop,通過RunLoop在里面不斷的循環,不斷的發送消息,讓他做事情.

1 - 基於NSURLConnection包裝的重要對象(iOS9-NSURLConnection已經不能使用)
AFHTTPRequestOperationManager
- 封裝了HTTP請求的常見處理
- GET\POST請求
- 解析服務器的響應數據
// 創建 // AFHTTPRequestOperationManager內部包裝了NSURLConnection AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
Snip20150926_5.png
1 - 1 AFHTTPRequestOperationManager的GET請求

Snip20150926_8.png
- 參數是不用拼接的,AFN內部會幫你遍歷字典然后幫你拼接完成,只需把參數傳入即可.
- 請求成功會來到第一個block,
id responseObject
這個參數,會自動幫你從服務器得到的JSON數據轉為字典或者數組(用id就是因為不一定返回的是什么數據.所以要用到id);他的內部無非也就是一個Request對象 -
NSError *error
返回的是錯誤信息
1 - 2 AFHTTPRequestOperationManager的POST請求
- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

Snip20150926_9.png
- POST請求和GET沒什么兩樣,無非就是把GET改為POST即可
2 - 基於NSURLSession包裝的重要對象.
AFHTTPSessionManager
- 封裝了HTTP請求的常見處理
- GET\POST請求
- 解析服務器的響應數據
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
Snip20150926_5.png
2 - 1AFHTTPSessionManager的GET請求
- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

Snip20150926_15.png
2 - 2 AFHTTPSessionManager的POST請求
- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

Snip20150926_16.png
AFN解析相關
- AFN在解析時候: 默認解析的是JSON數據.
- 我們通過他的一個內部方法可以看到
Snip20150926_22.png - 進入頭文件后可以看到他的默認處理器為JSON處理器
Snip20150926_24.png - 這樣的話,也就意味着,服務器返回的任何數據AFN內部都會當做JSON來處理
那么有時候服務器返回的是XML數據該怎么辦呢
-
如果想解析XML數據,就需要手動把
responseSerializer
的值改掉,就可以了
Snip20150926_30.png -
也就意味着這里的
id responseObject
,這里需要換做NSXMLParser *parser
Snip20150926_31.png

Snip20150926_32.png
那么有時候服務器返回的不是JSON也不是XML怎么辦呢
(比如文件的下載)

Snip20150926_33.png
- 這時,就要告訴AFN用最平常的數據來解析,服務器返回的是什么樣,就解析成什么樣即可
Snip20150926_34.png
服務器返回的數據解析的幾種方式
// 解析服務器返回的普通數據(直接使用 *服務器本來返回的數據* 不作任何解析) mgr.responseSerializer = [AFJSONResponseSerializer serializer]; // 解析服務器返回的XML數據 mgr.responseSerializer = [AFXMLParserResponseSerializer serializer]; // 解析服務器返回的JSON數據 (默認解析的是JSON可以不傳) mgr.responseSerializer = [AFJSONRequestSerializer serializer];
項目中的細節處理
有時候,可能當用戶在點擊一個控制器的button在請求數據時候,會遇到網速慢,返回的數據特別慢,用戶可能會等的不耐煩,然后退掉當前的控制器,但是這個請求是還存在着的,一旦請求返回,項目一定會崩潰.那么這種情況該怎么處理呢?
-
遇到這樣的情況,可以先把
AFNHTTPSessionManger
做一個屬性@property(nonatomic, strong)AFNHTTPSessionManger *manger
-
將所有的發請求的地方都用成
// 如果這樣使用AFN,會把所有的請求都放入`manger.operationQueue` self.manger POST/ GET
-
在
- (void)dealloc
方法中調用// 取消所有任務 self.manger.operationQueue cancelAllOperations