解讀 AFNetwork 3.x原始碼 與 AFNetwork 2.x
對比AFNetwork 3.x 與 AFNetwork 2.x
AFNetworking支援HTTP請求和基於REST的網路服務(包括GET、POST、 PUT以及DELETE等),支援ARC。AFNetworking專案中還包含一些列單元測試。
AFNetworking 2.0開始使用NSURLConnection的基礎API ,以及較新基於NSURLSession的API的選項。 AFNetworking 3.0現已完全基於NSURLSession的API,刪除了了對 NSURLConnection的封裝內容
這是因為NSURLSession能夠完全替代NSURLConnection,並且具有很多優點:
- 支援後臺執行的網路任務
- 暫停、停止、重啟網路任務,不需要自己封裝NSOperation
- 支援斷點續傳,非同步下載
- 支援上傳,非同步上傳
- 獲取下載、上傳的進度
注意:
3.0版本最低支援版本是從iOS7
1.廢棄的類
廢棄對NSURLConnection的支援
被刪除的類:
- AFURLConnectionOperation
- AFHTTPRequestOperation
- AFHTTPRequestOperationManager
用以替代的是下面的類:
- AFURLSessionManager
- AFHTTPSessionManager
進行修改的類:
- UIImageView+AFNetworking
- UIWebView+AFNetworking.h
- UIButton+AFNetworking.h
如果你之前的開發是基於AFHTTPRequestOperationManager的網路請求現在你應該轉到AFHTTPSessionManager下去進行
UIKit的遷移
圖片下載已經被重構,以遵循AlamofireImage架構與新的AFImageDownloader類。這個類的圖片下載職責的代理人是UIButton與UIImageView的類目,並且提供了一些方法,在必要時可以自定義。類別中,下載遠端圖片的實際方法沒有改變。
UIWebView的類目被重構為使用AFHTTPSessionManager作為其網路請求。
UIAlertView的類目被廢棄
從AFNetworking 3.0後UIAlertView的類目因過時而被廢棄。並沒有提供UIAlertController類目的計劃,因為這是應用程式應處理的邏輯,而不是這個庫。
下面進行新舊對比:
AFNetwork 2.x
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//設定網路請求超時時間
[manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
manager.requestSerializer.timeoutInterval = 30.0f;
[manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
[manager.requestSerializer setValue:@"application/x-www-form-urlencoded;" forHTTPHeaderField:@"Content-Type"];
[self addHeaderParams:manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html",nil];
[manager POST:self.requestURL
parameters:self.requestParams
success:^(AFHTTPRequestOperation *operation, id responseObject) {
(@"success-POST:%@",responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DebugLog(@"failurePOST:%@",error.description)
}];
AFNetworking 3.x
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
manager.requestSerializer.timeoutInterval = 30.0f;//30.0f
[manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
[manager.requestSerializer setValue:@"application/x-www-form-urlencoded;" forHTTPHeaderField:@"Content-Type"];
[self addHeaderParams:manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html",nil];
[manager POST:self.requestURL parameters:self.requestParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"success-POST:%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
即:每次開啟一個網路請求時,首先新建一個AFHTTPSessionManager,然後將相關的requestSerializer和reponseSerializer賦值;最後發起相應的GET/POST等請求。
如果是直接採用NSURLSession來請求網路,寫法如下:
NSURLSession *session = [NSURLSession
sessionWithConfiguration:
[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:nil
delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:completionHandler];
[dataTask resume];
即:新建一個Session(多個請求要用共享的SessionManager/Session),然後新建task,啟用task,完成網路請求。
共享原因:
共享的Session將會複用TCP的連線,而每次都新建Session的操作將導致每次的網路請求都開啟一個TCP的三次握手,共享會提升網路速度
AFNetworking 3.x 提供的post方法:
[manager POST: parameters: constructingBodyWithBlock: progress: success: failure:]
[manager POST: parameters: progress: success: failure:]
不建議使用的方法:
[manager POST: parameters: success: failure:];
[manager POST: parameters: constructingBodyWithBlock: success: failure:]
2. AFNetworking快取
AFNetworking實際上使用了兩個獨立的快取機制:
(1)AFImagecache:一個提供圖片記憶體快取的類,2.x時繼承自NSCache,3.x不再使用NSCache。AFImagecache3.x之前存在於UIImageView+AFNetwork,之後存在於AFAutoPurgingImageCache中。
(2)NSURLCache:仍使用原生快取機制:NSURLCache。NSURLConnection’s預設的URL快取機制,用於儲存NSURLResponse物件:一個預設快取在記憶體,通過配置可以快取到磁碟的類。NSURLCache對每個NSURLRequest物件都會遵守快取策略(NSURLRequestCachePolicy)。
注意:NSCache與NSURLCache沒有任何關係
3.0之前的快取方法:存在於AFURLConnectionOperation類檔案中。
- (void)setCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block;
3.0之後:在類AFURLSessionManager中
- (void)setDataTaskWillCacheResponseBlock:(nullable NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block;
描述:
Sets a block to be executed to determine the caching behavior of a data task, as handled by the
NSURLSessionDataDelegate
methodURLSession:dataTask:willCacheResponse:completionHandler:
.
@param block A block object to be executed to determine the caching behavior of a data task. The block returns the response to cache, and takes three arguments: the session, the data task, and the proposed cached URL response.
*/
蘋果系統快取儲存策略:
{
NSURLCacheStorageAllowed, //預設,可以存在記憶體(重啟裝置清除),可以儲存磁碟(程式碼清除)
NSURLCacheStorageAllowedInMemoryOnly,
NSURLCacheStorageNotAllowed,
} NSURLCacheStoragePolicy;
請求快取策略:
{
NSURLRequestUseProtocolCachePolicy = 0, //預設策略
NSURLRequestReloadIgnoringLocalCacheData = 1,//忽略本地快取,從源載入
NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // 忽略本地&伺服器快取,從源載入
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
NSURLRequestReturnCacheDataElseLoad = 2, //先從快取載入,如果沒有快取,從源載入
NSURLRequestReturnCacheDataDontLoad = 3, //離線模式,載入快取資料(無論是否過期),不從源載入
NSURLRequestReloadRevalidatingCacheData = 5 // 存在的快取資料先確認有效性,無效的話從源載入
};
typedef NSUInteger NSURLRequestCachePolicy;
清除所有的URL快取Response:
[[NSURLCache sharedURLCache] removeAllCachedResponses];