1. 程式人生 > >AFNetworking 3.0 使用詳解 和 源碼解析實現原理

AFNetworking 3.0 使用詳解 和 源碼解析實現原理

數據 syn ria 特定 style conn afn rda gre

AFN原理&& AFN如何使用RunLoop來實現的:

    NSString * requestURL = @"http://119.254.98.136/api/v1/web/homepage";
    
//    AFHTTPSessionManager * manager =[[AFHTTPSessionManager alloc] init];
    AFHTTPSessionManager * manager =[AFHTTPSessionManager manager];
    [manager GET:requestURL parameters:nil progress:nil success:
^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"請求成功了!"); NSLog(@"%@",responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"請求失敗了!"); }];

1、

- (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(
id)parameters progress:(void (^)(NSProgress * _Nonnull))downloadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure { NSURLSessionDataTask
*dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:downloadProgress success:success failure:failure]; [dataTask resume]; return dataTask; }

2、如果序列化失敗,就直接執行了failure block,否則繼續3

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                                       URLString:(NSString *)URLString
                                      parameters:(id)parameters
                                  uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
                                downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
                                         success:(void (^)(NSURLSessionDataTask *, id))success
                                         failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
{
    NSError *serializationError = nil;
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
    if (serializationError) {
        if (failure) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
#pragma clang diagnostic pop
        }

        return nil;
    }

    __block NSURLSessionDataTask *dataTask = nil;
    dataTask = [self dataTaskWithRequest:request
                          uploadProgress:uploadProgress
                        downloadProgress:downloadProgress
                       completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
        if (error) {
            if (failure) {
                failure(dataTask, error);
            }
        } else {
            if (success) {
                success(dataTask, responseObject);
            }
        }
    }];

    return dataTask;
}

3、

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
                               uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
                             downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
                            completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject,  NSError * _Nullable error))completionHandler {

    __block NSURLSessionDataTask *dataTask = nil;
    url_session_manager_create_task_safely(^{
        dataTask = [self.session dataTaskWithRequest:request];
    });

    [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];

    return dataTask;
}

4、對dataTask設置請求之後的回調Delegate和處理block

- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask
                uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
              downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
             completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
    AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
    delegate.manager = self;
    delegate.completionHandler = completionHandler;

    dataTask.taskDescription = self.taskDescriptionForSessionTasks;
    [self setDelegate:delegate forTask:dataTask];

    delegate.uploadProgressBlock = uploadProgressBlock;
    delegate.downloadProgressBlock = downloadProgressBlock;
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
#pragma clang diagnostic pop

表示在這個區間裏忽略一些特定的clang的編譯警告,因為AFNetworking作為一個庫被其他項目引用,所以不能全局忽略clang的一些警告,只能在有需要的時候局部這樣做,作者喜歡用?:符號,所以經常見忽略-Wgnu警告的寫法

NSURLConnection 是 Foundation URL 加載系統的基石。一個 NSURLConnection 異步地加載一個 NSURLRequest 對象,調用 delegate 的 NSURLResponse / NSHTTPURLResponse 方法,其 NSData 被發送到服務器或從服務器讀取;delegate 還可用來處理 NSURLAuthenticationChallenge、重定向響應、或是決定 NSCachedURLResponse 如何存儲在共享的 NSURLCache 上。

NSOperation 是抽象類,模擬單個計算單元,有狀態、優先級、依賴等功能,可以取消。

AFURLConnectionOperation將兩者結合, 作為 NSOperation 的子類,遵循 NSURLConnectionDelegate 的方法,可以從頭到尾監視請求的狀態,並儲存請求、響應、響應數據等中間狀態。

創建 AFURLConnectionOperation 並把它安排進 NSOperationQueue,通過設置 NSOperation 的新屬性 completionBlock,指定操作完成時如何處理 response 和 response data(或是請求過程中遇到的錯誤)。

AFNetworking 3.0 實現完全基於NSURLSessionTask進行封裝,NSURLSessionTask 是蘋果在iOS7 推出的網絡請求api。AF支持https,網絡數據請求,文件上傳,文件下載,監聽手機網絡狀態。AFHttpSessionManager 繼承 AFURLSessionManager 對網絡請求進行管理,使用AFURLRequestSerialization 對網絡請求進行封裝,使用AFURLReponseSerialization 響應體進行處理,使用AFSecurityPolicy 對服務器證書進行校驗。支持https協議,支持本地證書和服務器證書進行對比驗證,AF要求ios7或以上系統。AF數據傳遞主要使用block 和 notifacation的方式。

使用詳解

AFURLSessionManager 使用方法

1、請求服務器數據

2、上傳數據

3、多線程下載數據

AFHttpSessionManager 使用方法

1、post

2、get

3、上傳

AFSecurityPolicy

服務器和客戶端都生成相應的證書之後,iOS項目將服務器端的證書保存導入到項目中。接著AFN根據項目中的服務器的證書來進行驗證。

AFSecurityPolicy對服務器的驗證,保證訪問服務器的安全性。(這裏牽涉到Https和Http的不同,以及不同的驗證方式,請求有何不同。)

證書的驗證模式 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

  • AFSSLPinningModeNone

不做任何驗證,只要服務器返回了證書就通過

  • AFSSLPinningModePublicKey

只驗證公鑰部分,只要公鑰部分一致就驗證通過,如圖所示,紅色框起來的部分只要一致就通過

  • AFSSLPinningModeCertificate

除了公鑰外,其他能容也要一致才能通過驗證。

AFURLSessionManager

AFURLSessionManager管理所有的請求,session 設置了NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate 實現證書合法性校驗,數據傳輸進度檢測,數據請求成功或失敗的回調。

使用runtime 用af_supend 替換 suspend,用af_resume 替換了resume 當調用這兩個方法的時候往上層發送通知AFNetworkingTaskDidSuspendNotification AFNetworkingTaskDidResumeNotification

AFNetworking 3.0 使用詳解 和 源碼解析實現原理