当前位置:首页 > Web开发 > 正文

AFNetworking到底长啥样(下)

2024-03-31 Web开发

标签:

在AFNetworking到底长啥样(上)中简单介绍了AFN涉及的主要类及其结构,接下来以一个简单的POST请求探寻其内部是如何实现的。

一、环境搭建

服务器配置

本例中直接使用iMac自带的Apache,并为其开启PHP支持。在服务器目录下编写index.php文件如下:

<?php echo @"This is Layne‘s Response"; ?>

编写测试App

创建一个测试App,在主界面上增加一个按钮,在按钮的点击函数中发起网络请求,如下:

- (AFHTTPSessionManager *)manager{//lazy if(!_manager){ _manager = [AFHTTPSessionManager manager]; } return _manager; } - (void)click{ [self.manager POST:@"http://www.layne.com" parameters:@{@"name":@"layne",@"age":@30} headers:@{@"TestName":@"myTest"} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"success:%@",responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"fail:%@",error); }]; }

二、一个POST请求的前世今生

启动测试App,点击按钮。接下里让我们看看AFN是如何优雅的管理网络请求的。

1.初始化

AFHTTPSessionManager的初始化

self.manager是AFHTTPSessionManager的实例,它使用类方法+ manager初始化。这个类方法最终调用如下方法:

- (instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration { self = [super initWithSessionConfiguration:configuration];//①configuration=nil if (!self) { return nil; } // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"http://www.mamicode.com/"]) { url = [url URLByAppendingPathComponent:@""]; } self.baseURL = url; self.requestSerializer = [AFHTTPRequestSerializer serializer];//② self.responseSerializer = [AFJSONResponseSerializer serializer];//③ return self; }

①中调用父类的方法初始化父类相关属性,这包括:

operationQueue responseSerializer(为AFJSONResponseSerializer实例) securityPolicy(为默认,即不进行SSL验证) reachabilityManager mutableTaskDelegatesKeyedByTaskIdentifier(管理{taskID:delegate}) lock(用于操作mutableTaskDelegatesKeyedByTaskIdentifier时保证线程安全) session(NSURLSession实例,设置其代理为self,queue为operationQueue)

②中设置其requestSerializer为AFHTTPRequestSerializer实例,③重设其responseSerializer为AFJSONResponseSerializer实例。

AFHTTPRequestSerializer的初始化

requestSerializer被设置成了AFHTTPRequestSerializer的实例,初始化是通过类方法+serializer实现的。内容包括:

stringEncoding(为NSUTF8StringEncoding) mutableHTTPRequestHeaders(保存用户设置的header,默认会添加"Accept-Language"和"User-Agent",其中"User-Agent"还进行了ICU转换以保证必须为ASCII字符) HTTPMethodsEncodingParametersInURI(为GET、HEAD、DELETE) mutableObservedChangedKeyPaths (监听"allowsCellularAccess"、"cachePolicy"、"HTTPShouldHandleCookies"、"HTTPShouldUsePipelining"、"networkServiceType"、"timeoutInterval",一旦用户设置了这6个属性,则对应属性的名会被存入,最后其值会加到request中去,本质是增量添加:“谁改变添加谁”)

AFJSONResponseSerializer的初始化

responseSerializer被设置成为了AFJSONResponseSerializer的实例,初始化是通过类方法+serializer实现的。内容包括:

readingOptions(为0) acceptableStatusCodes(可接受的code,初始化为[200~199]) acceptableContentTypes(可接受的contenttype,设置为application/json、text/json、text/javascript) 注:其父类AFHTTPResponseSerializer的acceptableContentTypes=nil,即接受任何Content。

至此必要的初始化已完成。

2.发起请求 (1) POST

进入到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; }

即最终生成一个dataTask,然后resume启动,并将dataTask返回。

(2) 生成dataTask

生成的dataTask是通过如下函数实现的,本例中传入的参数值也已标明:

- dataTaskWithHTTPMethod: //@"POST" URLString: //@"http://www.layne.com" parameters: //@{@"name":@"layne",@"age":@30} headers: //@{@"TestName":@"myTest"} uploadProgress: //nil downloadProgress: //nil success: //successBlock{NSLog(@"success:%@",responseObject);} failure: //failureBlock{NSLog(@"fail:%@",error);}

其内部执行的步骤如下:

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/41599.html