AFNetworking POST操作

AFNetworking POST操作

網(wǎng)絡(luò)請求部分,我們上一片分析了GET請求源碼部分,通過這篇我們來了解關(guān)于POST請求的源碼部分,其實POST和GET實現(xiàn)過程是一樣的就是中間處理部分會出現(xiàn)略微差異。

POST操作

- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters headers:(nullable NSDictionary <NSString *, NSString *> *)headers progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters headers:headers uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
    
    [dataTask resume];
    
    return dataTask;
}

傳入的參數(shù)和GET方法相同:

  1. 請求的URL網(wǎng)址;
  2. 請求頭(字典);
  3. 上傳進度;
  4. 成功回調(diào);
  5. 失敗回調(diào);

同樣,返回的是一個NSURLSessionDataTask對象,并且實現(xiàn)了啟動任務(wù)[dataTask resume];。

進入POST源碼我們可以看到,實際上操作是和GET方法調(diào)用了一個方法。在這里我們就能清楚的意識到,從這里開始整個流程是一樣的,不過對于POST和GET方法是通過之前對Method來區(qū)分對待的。
在GET中method傳入的是@"GET",而在POST中傳入的是@"POST"。

  1. GET
[self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters headers:headers uploadProgress:nil downloadProgress:downloadProgress success:success failure:failure];
  1. POST
[self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters headers:headers uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];

保存方法

最后到達方法內(nèi)部,進行保存了HTTP請求方式為POST,此時的method為POST。

mutableRequest.HTTPMethod = method;

AFNetworking應(yīng)該注意的好的編程方法

這樣部分摘自GET和POST共同方法中,我們知道做網(wǎng)絡(luò)編程中,會出現(xiàn)錯誤問題,AFNetworking為我們做出了很好的典范,當我們設(shè)置了NSError *error后,需要判斷如果error出現(xiàn)了錯誤的情況,如果出現(xiàn)了錯誤,我們則需要開辟一條新的線程來做錯誤處理。

if (serializationError) {
        if (failure) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }
         
        return nil;
}

網(wǎng)絡(luò)編程遇到線程錯誤問題是非常常見的,因此,對于錯誤處理AFNetworking做的非常完善。

反向思考

看到這里,GET和POST的處理方式,是大抵相同的。我們反著梳理一遍思路。首先,要做GET和POST請求,我們需要知道請求網(wǎng)址,因為POST需要的內(nèi)容比GET多請求頭,因此,設(shè)計方法時候,將方法安裝POST方法設(shè)計,當GET調(diào)用時候,不需要的地方傳入nil即可,此時要能請求POST和GET方法,還需要生成NSURLSessionDataTask,要DataTask就需要NSURLRequest。所以,我們就專門對Request進行一次封裝,從用戶傳入的請求頭和請求方法獲得信息給Request。這樣,Request是帶著信息傳給NSURLSessionDataTask,這樣,就可以生成一個具有這些信息的DataTask。然后,啟動任務(wù)即可。
或許,你看到這里有疑惑,那成功做的事情和失敗做的事情以及進度條是怎么做的呢,的確,設(shè)計方法時候,AFNetworking將這三個板塊設(shè)計成為Block回調(diào),這樣就可以等請求完成后,繼續(xù)運行用戶傳入的東西。

這些回調(diào)原來系統(tǒng)需要使用協(xié)議來使用,AFNetworking自然會遵循這一個操作,因此,我們來看看AFNetworking封裝的協(xié)議。

AFNetworking封裝協(xié)議

- (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
{
    /* 通過dataTask實例化一個delegate對象 */
    AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];
    
    /* 將自身傳給delegate對象的管理者 */
    delegate.manager = self;
    
    delegate.completionHandler = completionHandler;

    /* 任務(wù)描述 */
    dataTask.taskDescription = self.taskDescriptionForSessionTasks;
    [self setDelegate:delegate forTask:dataTask];

    /* 傳入更新Block和下載Block塊 */
    delegate.uploadProgressBlock = uploadProgressBlock;
    delegate.downloadProgressBlock = downloadProgressBlock;
}

@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>

AFNetworking創(chuàng)建一個AFURLSessionManagerTaskDelegate來管理協(xié)議,這個協(xié)議繼承了NSURLSessionTaskDelegate,NSURLSessionDataDelegate,NSURLSessionDownloadDelegate這三個我們經(jīng)常使用的三個協(xié)議。

@property (nonatomic, weak) AFURLSessionManager *manager; //url話語管理者
@property (nonatomic, strong) NSMutableData *mutableData; //數(shù)據(jù)
@property (nonatomic, strong) NSProgress *uploadProgress; //更新進度
@property (nonatomic, strong) NSProgress *downloadProgress; //下載進度
@property (nonatomic, copy) NSURL *downloadFileURL; //下載文件的路徑

AFURLSessionManagerTaskDelegate將存儲每一個協(xié)議內(nèi)容,包括上傳進度,下載進度,下載文件路徑等。

在設(shè)置協(xié)議中,有趣的是,AFNetworking向我們展示了區(qū)別于RAC鎖住線程的方法。

- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate
            forTask:(NSURLSessionTask *)task
{
    NSParameterAssert(task);
    NSParameterAssert(delegate);

    [self.lock lock];
    self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
    [self addNotificationObserverForTask:task];
    
    [self.lock unlock];
}

利用NSLock來鎖住線程和釋放線程操作。通過字典存儲任務(wù)標識。為每個任務(wù)添加了通知。

@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableTaskDelegatesKeyedByTaskIdentifier;

在這一步里面也進行了計算進度的操作。

AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];

至此,我們已經(jīng)分析了大部分源碼了,如果有興趣的話,可以放下在AFNetworking中有對Delete實現(xiàn)的大量封裝,這一個封裝操作,下一篇會做詳細介紹,來幫助梳理如何學(xué)習AFNetworking一樣封裝Delegate。

中文源碼下載

AFNetworking中文源碼: GitHub

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容