最近一直在研究AFN坏瘩,覺(jué)得有必要記錄一下自己的心得,一是可以自己加深印象,二是可以幫助一下不太了解AFN的人柬脸,都是自己的一些觀點(diǎn)他去,若有錯(cuò)誤之處,還請(qǐng)大神幫忙指出來(lái)倒堕!覺(jué)得雞肋的請(qǐng)略過(guò)灾测,謝謝!
AFN最新版本已經(jīng)來(lái)到了3.x了垦巴,也從以前基于NSURLConnection重構(gòu)到基于NSURLSession的新版本媳搪。新版本的AFN更加簡(jiǎn)潔你只需要知道幾個(gè)主要的類就可以了解AFN的工作流程。先列舉一下:
1骤宣、AFURLSessionManager;
2秦爆、AFHTTPSessionManager;
3、AFURLRequestSerialization憔披;
4等限、AFURLResponseSerialization;
AFURLSessionManager 是AFN的核心文件芬膝,集成了管理請(qǐng)求的建立望门、管理、銷毀锰霜、安全筹误、請(qǐng)求重定向、請(qǐng)求重啟等功能癣缅。主要實(shí)現(xiàn)了對(duì)NSURLSession和NSURLSessionTask的封裝厨剪,以及重定向處理結(jié)果。
AFHTTPSessionManager 是AFURLSessionManager的子類友存,主要用于處理HTTP和HTTPS的請(qǐng)求丽惶,我們平時(shí)用的最多的也是這個(gè)類,對(duì)這個(gè)類做一個(gè)二次封裝爬立,然后完成我們請(qǐng)求接口的業(yè)務(wù)。
AFURLRequestSerialization這個(gè)類說(shuō)白了就是創(chuàng)建一個(gè)NSURLRequest請(qǐng)求體万哪,AFN直接把這一塊給抽離出來(lái)侠驯,把所有關(guān)于request的業(yè)務(wù)都放在了這里,如設(shè)置GET\POST方法奕巍,設(shè)置請(qǐng)求頭吟策、超時(shí)時(shí)間、請(qǐng)求的緩存策略的止、如何處理請(qǐng)求參數(shù)(GET與POST的方法不同)檩坚,清晰明了!
AFURLResponseSerialization 很明顯這個(gè)類是用來(lái)處理網(wǎng)絡(luò)請(qǐng)求的返回值的。對(duì)返回?cái)?shù)據(jù)序列化匾委、編碼解碼拖叙、數(shù)據(jù)處理等。這里AFURLResponseSerialization只是一個(gè)協(xié)議赂乐,AFHTTPResponseSerializer類遵守這個(gè)協(xié)議薯鳍,實(shí)現(xiàn)了協(xié)議方法,還有其他幾個(gè)類繼承了AFHTTPResponseSerializer挨措,如:AFJSONResponseSerializer挖滤、AFXMLParserResponseSerializer、AFPropertyListResponseSerializer浅役、AFImageResponseSerializer斩松,所以在處理數(shù)據(jù)的時(shí)候,看你的返回值是什么類型的就用那個(gè)類去處理就好了觉既,AFN使用的是AFJSONResponseSerializer惧盹。
廢話不多說(shuō),上代碼:
1奋救、AFHTTPSessionManager中岭参,常用的兩個(gè)請(qǐng)求方法,POST\GET方法
- (NSURLSessionDataTask *)POST:(NSString *)URLString
? ? ? ? ? ? ? ? ? ? parameters:(id)parameters
? ? ? ? ? ? ? ? ? ? ? progress:(void (^)(NSProgress * _Nonnull))uploadProgress
? ? ? ? ? ? ? ? ? ? ? success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
? ? ? ? ? ? ? ? ? ? ? failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
? ? NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
? ? [dataTask resume];
? ? return dataTask;
}
- (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;
}
//兩個(gè)方法都調(diào)用了dataTaskWithHTTPMethod:這個(gè)方法尝艘,返回一個(gè)task,這個(gè)task就是我們的請(qǐng)求任務(wù)演侯。拿到這個(gè)//task我們還可以Cancel請(qǐng)求。下面去看看?dataTaskWithHTTPMethod:這個(gè)方法背亥。
- (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;
//這里使用requestSerialize 去獲取一個(gè)request請(qǐng)求體秒际,如果是post就把參數(shù)設(shè)置在body里,如果是get就把鍵值對(duì)添加到url后面,關(guān)于baseURL使用的時(shí)候可以去SDK的介紹中去看看狡汉,介紹的很清楚娄徊。
??? 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;
??? }
//這里創(chuàng)建下載任務(wù)、跳轉(zhuǎn)到AFURLSessionManager去執(zhí)行方法盾戴,block是成功和失敗的回調(diào)寄锐。注意success參數(shù)是task,responseObject,failure的參數(shù)的task和error尖啡;
??? __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;
}
接下來(lái)去AFURLSessionManger中去看生成task的方法橄仆。
- (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;
//很明顯,在這里生成了task衅斩,self.session就是NSURLSession盆顾,在創(chuàng)建AFURLSessionManger的是就創(chuàng)建了,這里session是默認(rèn)是defaultSessionConfiguration格式的畏梆,AFURLSessionManger會(huì)實(shí)現(xiàn)session的代理方法您宪,不過(guò)奈懒,不會(huì)在這里處理這些方法返回的數(shù)據(jù),而是做了一個(gè)重定向宪巨,轉(zhuǎn)到別的地方去處理了磷杏。具體在哪處理,往下看揖铜。茴丰。。
? ? url_session_manager_create_task_safely(^{
? ? ? ? dataTask = [self.session dataTaskWithRequest:request];
? ? });
//這里是定義的處理重定向數(shù)據(jù)的代理
? ? [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
? ? return dataTask;
}
//生成代理對(duì)象天吓,注意:這里只有一個(gè)session贿肩,卻生成了多個(gè)task。代理方法返回的數(shù)據(jù)可以根據(jù)task.taskIdentifier來(lái)區(qū)分是那個(gè)任務(wù)返回?cái)?shù)據(jù)了龄寞。之所以使用一個(gè)session汰规,http的底層其實(shí)也是通過(guò)TCP/IP完成的,只不過(guò)http是一問(wèn)一答物邑,回答以后就結(jié)束鏈接了溜哮,但是在建立鏈接和斷開(kāi)連接的時(shí)候需要三次握手、四次揮手色解,每次建立鏈接會(huì)消耗一定的內(nèi)存茂嗓。但是在使用NSURLSession以后,可以復(fù)用TCP鏈接科阎。這也是iOS9以后述吸,NSURLConnection背棄的原因之一吧。
- (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;
}
- (void)addDelegateForUploadTask:(NSURLSessionUploadTask *)uploadTask
??????????????????????? progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock
?????????????? completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
??? AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
??? delegate.manager = self;
??? delegate.completionHandler = completionHandler;
??? uploadTask.taskDescription = self.taskDescriptionForSessionTasks;
??? [self setDelegate:delegate forTask:uploadTask];
??? delegate.uploadProgressBlock = uploadProgressBlock;
}
AFURLSessionManagerTaskDelegate這個(gè)就是重定向去處理回調(diào)數(shù)據(jù)的類锣笨。AFURLSessionManagerTaskDelegat里面會(huì)有很多對(duì) task屬性的KVO監(jiān)聽(tīng)蝌矛,以此來(lái)保證數(shù)據(jù)的實(shí)時(shí)性。當(dāng)task任務(wù)完成以后错英,通過(guò)block回調(diào)數(shù)據(jù)入撒,然后移除KVO.
暫時(shí)寫(xiě)到這里,大概就是一個(gè)流水賬椭岩,主要是自己加深印象茅逮,有問(wèn)題的請(qǐng)指出,覺(jué)得很雞肋的請(qǐng)略過(guò)判哥!