日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

小白的AFNetWorking之路

發布時間:2025/3/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小白的AFNetWorking之路 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

淘汰掉了ASIHTTPRequest和MKNetworkit,AFNetworking完美勝出

起初

新建一個工程HelloWorld,你想在這個工程中通過pod來集成使用第三方庫AFNetworking。

使用終端進入工程根目錄,然后編輯Podfile:

vim Podfile

【這里你也許會遇到一個問題終端左下角會提示E353:Nothing in register,不要慌,這并不是什么問題,而是自己操作錯誤,這時候只要按【i】或者【a】進入vi的插入模式就可以編輯了】

這里普及一下vi的工作模式:

1、命令行模式:用光標在字符之間來回移動,進行刪除、復制、移動字符等操作,按【i】或者【a】進入插入模式,按【:】(冒號)進入末行模式;

2、插入模式:輸入你要編輯的內容,按【esc】返回命令行模式,按【:】(冒號)進入末行模式;

3、末行模式:保存文件或者退出vi,輸入【wq】存盤并退出vi,輸入【q!】不保存強制退出vi,輸入【w:filename】將文件保存為制定的文件名。

結束上述Podfile編輯后,在終端運行

pod install

【 相關命令`pod repo update` or with `pod install --repo-update`】

了解

AFNetworking框架由會話(NSURLSeeion)、網絡監聽模塊(Reachability)、網絡安全模塊(Security)、請求序列化(Serialization)、響應序列化(Serialization)和UIKit集成模塊(UIKit)構成

如圖:

庫中最核心的類是AFURLSessionManager,使用頻率最高的是其子類AFHTTPSessionManager,在該類中包含了負責請求序列化的AFURLRequestSerialization和響應序列化AFURLResponseSerializer,AFURLSessionManager還提供了會話模塊NSURLSession、保證網絡安全的AFSecurityPolicy、網絡監聽的AFNetworkReachabilityManager。

如圖:

使用

首先在頭部導入#import <AFNetworking/AFNetworking.h>

寫個get請求

// 實現一個get請求 -(void)makeGetRequest{AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];NSDictionary *headerDic = [NSDictionary dictionaryWithObjectsAndKeys:@"application/json",@"Content-Type", nil];[sessionManager GET:@"http://wna.test.com/app" parameters:nil headers:headerDic progress:^(NSProgress * _Nonnull downloadProgress) {} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {NSLog(@"接口請求成功-- %@",responseObject);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"接口請求失敗-- %@",error);}]; }

寫個post請求

// 實現一個post請求 - (void)makePostRequest{AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];NSDictionary *headerDic = @{@"nbp-app-name":@"dog",@"Content-Type":@"application/json",};NSDictionary *parames = @{@"methodType":@"GET",@"moduleName":@"app-product",@"url":@"product/new_product_list",};[sessionManager POST:@"http://wna.test.com/app" parameters:parames headers:headerDic progress:^(NSProgress * _Nonnull uploadProgress) {} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {NSData *tempDisplay = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil];NSString *result = [[NSString alloc] initWithData:tempDisplay encoding:NSUTF8StringEncoding];NSLog(@"接口請求成功-- %@",result);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"接口請求失敗-- %@",error);}]; }

方法的逐級調用

get方法的源碼:

- (NSURLSessionDataTask *)GET:(NSString *)URLStringparameters:(nullable id)parametersheaders:(nullable NSDictionary <NSString *, NSString *> *)headersprogress:(nullable void (^)(NSProgress * _Nonnull))downloadProgresssuccess:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))successfailure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"URLString:URLStringparameters:parametersheaders:headersuploadProgress:nildownloadProgress:downloadProgresssuccess:successfailure:failure];[dataTask resume];return dataTask; }

入參有請求的URL,參數,請求頭,進度Block,成功Block和失敗Block。在這個方法中初始化了一個NSURLSessionDataTask的類,NSURLSessionDataTask繼承自NSURLSessionTask,NSURLSessionDataTask不提供NSURLSessionTask的任何附加功能,他的存在是為了區別于上載NSURLSessionUploadTask和下載NSURLSessionDownloadTask。

繼續往下看

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)methodURLString:(NSString *)URLStringparameters:(nullable id)parametersheaders:(nullable NSDictionary <NSString *, NSString *> *)headersuploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressdownloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgresssuccess:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))successfailure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure {NSError *serializationError = nil;NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];for (NSString *headerField in headers.keyEnumerator) {[request setValue:headers[headerField] forHTTPHeaderField:headerField];}if (serializationError) {if (failure) {dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{failure(nil, serializationError);});}return nil;}__block NSURLSessionDataTask *dataTask = nil;dataTask = [self dataTaskWithRequest:requestuploadProgress:uploadProgressdownloadProgress:downloadProgresscompletionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {if (error) {if (failure) {failure(dataTask, error);}} else {if (success) {success(dataTask, responseObject);}}}];return dataTask; }

在這個方法的實現里主要做了兩個事情:

  • 實例化NSMutableURLRequest對象
  • 實例化NSURLSessionDataTask對象,并返回
  • 在這個方法里是通過一個實現了AFURLRequestSerialization協議的請求序列化實例對象AFHTTPRequestSerializer來調用其實例方法得到一個NSMutableURLRequest對象。

    - (nullable NSMutableURLRequest *)requestWithMethod:(NSString *)methodURLString:(NSString *)URLStringparameters:(nullable id)parameterserror:(NSError * _Nullable __autoreleasing *)error;

    我們看下該方法的實現

    - (NSMutableURLRequest *)requestWithMethod:(NSString *)methodURLString:(NSString *)URLStringparameters:(id)parameterserror:(NSError *__autoreleasing *)error {NSParameterAssert(method);NSParameterAssert(URLString);// 初識化URLNSURL *url = [NSURL URLWithString:URLString];NSParameterAssert(url);// 初始化RequestNSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url];// 設置請求方式mutableRequest.HTTPMethod = method;// 為某些屬性賦值【allowsCellularAccess,cachePolicy,HTTPShouldHandleCookies,HTTPShouldUsePipelining,networkServiceType,timeoutInterval】for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {if ([self.mutableObservedChangedKeyPaths containsObject:keyPath]) {[mutableRequest setValue:[self valueForKeyPath:keyPath] forKey:keyPath];}}// 調用實現的協議mutableRequest = [[self requestBySerializingRequest:mutableRequest withParameters:parameters error:error] mutableCopy];return mutableRequest; }

    在實現的協議中,真正的完成了一條完整的請求,請求地址,請求頭,請求體

    - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)requestwithParameters:(id)parameterserror:(NSError *__autoreleasing *)error {NSParameterAssert(request);NSMutableURLRequest *mutableRequest = [request mutableCopy];[self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {if (![request valueForHTTPHeaderField:field]) {// 設置請求頭[mutableRequest setValue:value forHTTPHeaderField:field];}}];// 序列化參數 用&拼接NSString *query = nil;if (parameters) {if (self.queryStringSerialization) {NSError *serializationError;query = self.queryStringSerialization(request, parameters, &serializationError);if (serializationError) {if (error) {*error = serializationError;}return nil;}} else {switch (self.queryStringSerializationStyle) {case AFHTTPRequestQueryStringDefaultStyle:query = AFQueryStringFromParameters(parameters);break;}}}// 如果是GET,HEAD,DELETE 走這邊if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {// 將序列化的參數拼到后面if (query && query.length > 0) {mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]];}} else {// POST、PUT走這里// #2864: an empty string is a valid x-www-form-urlencoded payloadif (!query) {query = @"";}// 如果沒有設置Content-Type,此處默認設置成application/x-www-form-urlencodedif (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {[mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];}// 配置請求體[mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];}return mutableRequest; }

    上面這塊是NSMutableURLRequest的整個過程,下面看下NSURLSessionDataTask

    - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)requestuploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlockdownloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlockcompletionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler {NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];return dataTask; }

    該方法中通過NSURLSession創建了一個NSURLSessionDataTask對象,并給dataTask添加代理

    在session的初始化中添加了安全鎖,保證了線程的安全。

    - (NSURLSession *)session {@synchronized (self) {if (!_session) {_session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];}}return _session; } - (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTaskuploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlockdownloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlockcompletionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler {AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];delegate.manager = self;delegate.completionHandler = completionHandler;dataTask.taskDescription = self.taskDescriptionForSessionTasks;[self setDelegate:delegate forTask:dataTask];delegate.uploadProgressBlock = uploadProgressBlock;delegate.downloadProgressBlock = downloadProgressBlock; }

    上面就是一條完整的調用流程,回到最初的地方[dataTask resume];開始網絡請求

    AFN使用技巧

  • 創建一個工具類,繼承自AFNetwork的請求管理者
  • 工具類中提供一個單例方法和一個基本的請求路徑,提供對GET和POST的請求封裝
  • 發送請求使用自己封裝的工具類
  • 方便修改,如果修改了底層的依賴框架,只用修改工具類就可以了
  • 相關面試問題:

    AFURLSessionManager主要負責哪些功能?

  • 創建和管理NSURLSession、NSURLSessionTask
  • 實現NSURLSessionDelegate等協議的代理方法
  • 引入AFSecurityPolicy保證請求的網絡安全(證書的校驗。公鑰的驗證等)
  • 引入AFNetworkReachabilityManager監聽網絡狀態
  • ?

    ?

    ?

    ?

    ?

    ?

    ?

    總結

    以上是生活随笔為你收集整理的小白的AFNetWorking之路的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。