AFNetworking 實(shí)現(xiàn)原理

一 .實(shí)現(xiàn)步驟?

?NSString *requestUrl ?=@"";

AFHTTPSessionManager ?*manager ? =[[AFHTTPSessionManager alloc]init]; [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 .上面是封裝在最外層的方法,點(diǎn)進(jìn)去是不管是get還是post調(diào)用的都是全能方法- (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.對請求進(jìn)行序列化(序列化是將數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)為二進(jìn)制串,既可以理解為將用戶名,密碼等字符串轉(zhuǎn)為二進(jìn)制流),如果序列化失敗,就執(zhí)行failure block 否則繼續(xù)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.配置?NSMutableURLRequest?對象就需要配置?NSURLSessionDataTask?對象了。主要分為2個(gè)步驟,第一個(gè)步驟是創(chuàng)建?NSURLSessionDataTask?對象實(shí)例,第二個(gè)步驟是給NSURLSessionDataTask?對象實(shí)例設(shè)置?Delegate。用于實(shí)時(shí)了解網(wǎng)絡(luò)請求的過程。

- (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;

}

4 .對每一個(gè)NSURLSessionDataTask的dataTask增加代理的具體實(shí)現(xiàn),對dataTask設(shè)置請求之后的回調(diào)Delegate和處理block,AFN 的代理統(tǒng)一使用AFURLSessionManagerTaskDelegate對象來管理NSURLSessionTask網(wǎng)絡(luò)請求過程中的回調(diào),然后在傳入AFN進(jìn)行管理,如代碼所示AFURLSessionManagerTaskDelegate?接管了NSURLSessionTaskDelegate,NSURLSessionDataDelegate,NSURLSessionDownloadDelegate的各種回調(diào),然后做內(nèi)部處理。這也是第三方網(wǎng)絡(luò)請求框架的重點(diǎn),讓網(wǎng)絡(luò)請求更加易用,好用

- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask

? ? ? ? ? ? ? ? uploadProgress:(nullable void(^)(NSProgress *uploadProgress)) uploadProgressBlock

? ? ? ? ? ? ? downloadProgress:(nullable void(^)(NSProgress *downloadProgress)) downloadProgressBlock

? ? ? ? ? ? completionHandler:(void(^)(NSURLResponse *response,idresponseObject, 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;

}

AFNetworking 3.0 實(shí)現(xiàn)完全基于NSURLSessionTask進(jìn)行封裝,NSURLSessionTask 是蘋果在iOS7 推出的網(wǎng)絡(luò)請求api。AF支持https,網(wǎng)絡(luò)數(shù)據(jù)請求,文件上傳,文件下載,監(jiān)聽手機(jī)網(wǎng)絡(luò)狀態(tài)。AFHttpSessionManager 繼承 AFURLSessionManager 對網(wǎng)絡(luò)請求進(jìn)行管理,使用AFURLRequestSerialization 對網(wǎng)絡(luò)請求進(jìn)行封裝,使用AFURLReponseSerialization 響應(yīng)體進(jìn)行處理,使用AFSecurityPolicy 對服務(wù)器證書進(jìn)行校驗(yàn)。支持https協(xié)議,支持本地證書和服務(wù)器證書進(jìn)行對比驗(yàn)證,AF要求ios7或以上系統(tǒng)。AF數(shù)據(jù)傳遞主要使用block 和 notifacation的方式。

post和get的不同:如果是 Post 請求,那么請求參數(shù)是沒有拼接在 URL 上面,而是放在?body?上,這是 Post 和 Get 請求的最大區(qū)別了,其他過程和Get 請求并沒有太多區(qū)別。

總結(jié)

AFN發(fā)起Get請求主要分為以下步驟:

1.創(chuàng)建NSURLSessionDataTask

2.配置NSURLSessionDataTask

3.設(shè)置NSURLSessionDataTask的Delegate

4.調(diào)用NSURLSessionDataTask的resume方法開始請求

5.在Delegate的方法里面處理網(wǎng)絡(luò)請求的各個(gè)過程

6.清理NSURLSessionDataTask的配置

其實(shí)也就是使用NSURLSessionDataTask的步驟,AFN在這幾個(gè)步驟加了一些封裝,讓我們的使用更簡單。

補(bǔ)充:NSURLSession是2013年iOS 7發(fā)布的用于替代NSURLConnection的,iOS 9之后NSURLConnection徹底推出歷史舞臺(tái)

使用: 以get請求為例

1.配置請求資源

NSURL *url = [NSURL URLWithString:@"http://api.nohttp.net/method?name=yanzhenjie&pwd=123"];

2.創(chuàng)建一個(gè)NSRequest請求對象

// 創(chuàng)建Request請求NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

? ? // 配置Request請求

? ? // 設(shè)置請求方法[request setHTTPMethod:@"GET"];

? ? // 設(shè)置請求超時(shí) 默認(rèn)超時(shí)時(shí)間60s[request setTimeoutInterval:10.0];

? ? // 設(shè)置頭部參數(shù)[request addValue:@"gzip"forHTTPHeaderField:@"Content-Encoding"];

? ? //或者下面這種方式 添加所有請求頭信息request.allHTTPHeaderFields=@{@"Content-Encoding":@"gzip"};

? ? //設(shè)置緩存策略[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

3.創(chuàng)建NSURLSession會(huì)話對象

NSURLSession *sharedSession = [NSURLSession sharedSession];

// 構(gòu)造NSURLSessionConfigurationNSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

? ? // 構(gòu)造NSURLSession,網(wǎng)絡(luò)會(huì)話;NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

4.) 創(chuàng)建NSURLSessionTask對象,然后執(zhí)行

// 構(gòu)造NSURLSessionTask,會(huì)話任務(wù);NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

? ? ? ? // 請求失敗,打印錯(cuò)誤信息if (error) {

? ? ? ? ? ? NSLog(@"get error :%@",error.localizedDescription);

? ? ? ? }

? ? ? ? //請求成功,解析數(shù)據(jù)else {

? ? ? ? ? ? // JSON數(shù)據(jù)格式解析idobject= [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];

? ? ? ? ? ? // 判斷是否解析成功if (error) {

? ? ? ? ? ? ? ? NSLog(@"get error :%@",error.localizedDescription);

? ? ? ? ? ? }else {

? ? ? ? ? ? ? ? NSLog(@"get success :%@",object);

? ? ? ? ? ? ? ? // 解析成功,處理數(shù)據(jù),通過GCD獲取主隊(duì)列,在主線程中刷新界面。dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? ? ? ? ? // 刷新界面....? ? ? ? ? ? ? ? });

? ? ? ? ? ? }

? ? ? ? }

? ? }];

更詳細(xì)的鏈接:https://www.cnblogs.com/whoislcj/p/6369717.html

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

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

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