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


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

讓你介紹一下AFN源碼的理解,首先要說說封裝里面主要做了那些重要的事情,有那些重要的類(XY題)

一、AFN的實現步驟:

    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、GET,或者POST等方法調用抽象的請求方法,指明相應的請求參數,(類似全能初始化方法的作用一下,最后不管多少個初始化參數的方法,都最后是調用了全能初始化方法),不管是什么形式的數據請求,最后是調用了全能數據請求的方法。指明數據請求的方式以及全能的參數。

- (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的dataTask增加代理

- (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、對每一個NSURLSessionDataTask的dataTask增加代理的具體實現,對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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM