AFNetworking到底长啥样(下)
标签:
在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