Blog: Dravenesshtml
关注仓库,及时得到更新:iOS-Source-Code-Analyzegit
在这一系列的文章中,我会对 AFNetworking 的源代码进行分析,深刻了解一下它是如何构建的,如何在平常中完成发送 HTTP 请求、构建网络层这一任务。github
AFNetworking 是现在 iOS 开发中不可缺乏的组件之一。它的 github 配置上是以下介绍的:json
Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac.安全
能够说使用 AFNetworking 的工程师构成的社区才使得它变得很是重要。服务器
咱们今天是来深刻研究一下这个与咱们平常开发密切相关的框架是如何实现的。网络
这是我对 AFNetworking 整个架构的理解,随后一系列的文章也会逐步分析这些模块。session
在这篇文章中,咱们有两个问题须要了解:架构
如何使用 NSURLSession 发出 HTTP 请求app
如何使用 AFNetworking 发出 HTTP 请求
NSURLSession
以及与它相关的类为咱们提供了下载内容的 API,这个 API 提供了一系列的代理方法来支持身份认证,而且支持后台下载。
使用 NSURLSession
来进行 HTTP 请求而且得到数据总共有五个步骤:
实例化一个 NSURLRequest/NSMutableURLRequest
,设置 URL
经过 - sharedSession
方法获取 NSURLSession
在 session 上调用 - dataTaskWithRequest:completionHandler:
方法返回一个 NSURLSessionDataTask
向 data task 发送消息 - resume
,开始执行这个任务
在 completionHandler 中将数据编码,返回字符串
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://github.com"]]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", dataStr); }]; [task resume];
这一段代码能够说是使用 NSURLSession
发送请求最简单的一段代码了,当你运行这段代码会在控制台看到一坨 github 首页的 html。
<!DOCTYPE html> <html lang="en" class=""> <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#"> <meta charset='utf-8'> ... </head> ... </html>
AFNetworking 的使用也是比较简单的,使用它来发出 HTTP 请求有两个步骤
以服务器的主机地址或者域名生成一个 AFHTTPSessionManager 的实例
调用 - GET:parameters:progress:success:failure:
方法
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[[NSURL alloc] initWithString:@"hostname"]]; [manager GET:@"relative_url" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"%@" ,responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@", error); }];
注意:在 iOS9 中,苹果默认全局 HTTPs,若是你要发送不安全的 HTTP 请求,须要在 info.plist 中加入以下键值对才能发出不安全的 HTTP 请求
还有一件事情是要注意的是,AFNetworking 默认接收 json 格式的响应(由于这是在 iOS 平台上的框架,通常不须要 text/html),若是想要返回 html,须要设置
acceptableContentTypes
在这一节中咱们要分析一下在上面两个方法的调用栈,首先来看的是 AFHTTPSessionManager
的初始化方法 - initWithBaseURL:
- [AFHTTPSessionManager initWithBaseURL:] - [AFHTTPSessionManager initWithBaseURL:sessionConfiguration:] - [AFURLSessionManager initWithSessionConfiguration:] - [NSURLSession sessionWithConfiguration:delegate:delegateQueue:] - [AFJSONResponseSerializer serializer] // 负责序列化响应 - [AFSecurityPolicy defaultPolicy] // 负责身份认证 - [AFNetworkReachabilityManager sharedManager] // 查看网络链接状况 - [AFHTTPRequestSerializer serializer] // 负责序列化请求 - [AFJSONResponseSerializer serializer] // 负责序列化响应
从这个初始化方法的调用栈,咱们能够很是清晰地了解这个框架的结构:
其中 AFURLSessionManager
是 AFHTTPSessionManager
的父类
AFURLSessionManager
负责生成 NSURLSession
的实例,管理 AFSecurityPolicy
和 AFNetworkReachabilityManager
,来保证请求的安全和查看网络链接状况,它有一个 AFJSONResponseSerializer
的实例来序列化 HTTP 响应
AFHTTPSessionManager
有着本身的 AFHTTPRequestSerializer
和 AFJSONResponseSerializer
来管理请求和响应的序列化,同时依赖父类提供的接口保证安全、监控网络状态,实现发出 HTTP 请求这一核心功能
初始化方法很好地揭示了 AFNetworking 整个框架的架构,接下来咱们要经过分析另外一个方法 - GET:parameters:process:success:failure:
的调用栈,看一下 HTTP 请求是如何发出的:
- [AFHTTPSessionManager GET:parameters:process:success:failure:] - [AFHTTPSessionManager dataTaskWithHTTPMethod:parameters:uploadProgress:downloadProgress:success:failure:] // 返回 NSURLSessionDataTask #1 - [AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:] // 返回 NSMutableURLRequest - [AFURLSessionManager dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:] // 返回 NSURLSessionDataTask #2 - [NSURLSession dataTaskWithRequest:] // 返回 NSURLSessionDataTask #3 - [AFURLSessionManager addDelegateForDataTask:uploadProgress:downloadProgress:completionHandler:] - [AFURLSessionManagerTaskDelegate init] - [AFURLSessionManager setDelegate:forTask:] - [NSURLSessionDataTask resume]
在这里 #1
#2
#3
处返回的是同一个 data task,咱们能够看到,在 #3
处调用的方法 - [NSURLSession dataTaskWithRequest:]
和只使用 NSURLSession
发出 HTTP 请求时调用的方法 - [NSURLSession dataTaskWithRequest:completionHandler:]
差很少。在这个地方返回 data task 以后,咱们再调用 - resume
方法执行请求,并在某些事件执行时通知代理 AFURLSessionManagerTaskDelegate
AFNetworking 实际上只是对 NSURLSession
高度地封装, 提供一些简单易用的 API 方便咱们在 iOS 开发中发出网络请求并在其上更快地构建网络层组件并提供合理的接口.
到这里,这一篇文章从上到下对 AFNetworking 是如何调用的进行了一个简单的概述,我会在随后的文章中会具体介绍 AFNetworking 中的每个模块,了解它们是如何工做,而且如何合理地组织到一块儿的。
关于其余 AFNetworking 源代码分析的其余文章:
关注仓库,及时得到更新:iOS-Source-Code-Analyze
Blog: Draveness