主要参考:
AFNetworking 概述
AFNetworking 是如今 iOS 开发中不可缺少的组件之一。
一. 概述
AFNetworking
架构:
AFNetworking 整体 架构:
-
AFURLSessionManager
的mutableTaskDelegatesKeyedByTaskIdentifier
属性,存放着每一个task对应的AFURLSessionManagerTaskDelegate
; -
AFURLSessionManager的NSURLSessionDelegate
实现,会调用每个task
对应的AFURLSessionManagerTaskDelegate
; -
设置
Task
的AFURLSessionManagerTaskDelegate
时,用了NSLock
,进行多线程同步; -
任务的调度采用了工厂模式、观察者和代理模式。
工厂模式:
对于HTTP协议的请求有:
AFHTTPRequestSerializer
AFJSONRequestSerializer
AFPropertyListRequestSerializer
三个都依赖抽象接口AFURLRequestSerialization
对于HTTP协议的响应有:
AFHTTPResponseSerializer
AFJSONResponseSerializer
AFXMLParserResponseSerializer
AFXMLDocumentResponseSerializer
AFPropertyListResponseSerializer
AFImageResponseSerializer
AFCompoundResponseSerializer
都依赖抽象接口 AFURLResponseSerialization
符合 开放-封闭原则,对增加新的请求头、响应头是开放的,而且增加新内容不需要修改原内容
观察者模式:
对于task
的每个生命周期,都会有相应的事件发出
AFNetworkingTaskDidResumeNotification
AFNetworkingTaskDidSuspendNotification
对于task
用KVO
的方式去监听Progress
代理模式:
AFURLSessionManagerTaskDelegate
是AF
对自己的逻辑封装,同时实现了
NSURLSessionTaskDelegate,
NSURLSessionDataDelegate
NSURLSessionDownloadDelegate
同时通过实现NSURLSessionDelegate
,来接受session
级别的事件。
首先了解两个问题:
- 如何使用
NSURLSession
发出HTTP
请求 - 如何使用
AFNetworking
发出HTTP
请求
二.NSURLSession
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
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); }];
注意:在
image.pngiOS9
中,苹果默认全局HTTPs
,如果你要发送不安全的HTTP
请求,需要在info.plist
中加入如下键值对才能发出不安全的HTTP
请求
还有一件事情是要注意的是,AFNetworking
默认接收json
格式的响应(因为这是在iOS
平台上的框架,一般不需要text/html
),如果想要返回html
,需要设置acceptableContentTypes
三.AFNetworking调用栈
在这一节中我们要分析一下在上面两个方法的调用栈,首先来看是AFHTTPSessionManager
的初始化方法- initWithBaseURL:
- [AFHTTPSessionManager initWithBaseURL:]
- [AFHTTPSessionManager initWithBaseURL: sessionConfiguration:]
- [AFURLSeesionManager initWithSessionConfiguration:]
- [NSURLSession sessionWithConfiguration:delegate:delegateQueue:】
- [AFJSONResponseSerializer serializer] // 负责序列化响应
- [AFSecurityPolicy defaultPolicy] // 负责身份认证
- [AFNetworkReachabilityManager sharedManager] // 查看网络连接情况
- [AFHTTPResquestSerializer serializer] // 负责序列化请求
- [AFJSONResponseSerializer serializer] // 负责序列化响应
从这个初始化方法的调用栈,我们可以非常清晰的了解这个框架的结构:
-
其中,
AFURLSessionManager
是AFHTTPSessionMangaer
父类 -
AFURLSessionManager
负责生成NSURLSession
的实例,管理AFSecurityPolicy
和AFNetworkReachabilityManager
, 来保证请求的安全和查看网络连接情况,它有一个AFJSONResponseSerializer
的实例来序列化HTTP
响应。 -
AFHTTPSessionManager
有着自己的AFHTTPRequestSerializer
和AFJSONResponseSerializer
来管理请求和响应的序列化,,同时依赖父类提供的接口保证安全、监控网络状态,实现发出HTTP
请求这一核心功能。
初始化方法很好的揭示了AFNetworking
整个框架的架构,接下来我们要通过分析另一个方法:- GET: parameters: process:success:failurse:
的调用栈,看一下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流程图.pngAFNetworking
实际上只是对NSURLSession
高度封装,提供一些简单易用的api
方便我们在iOS
开发总发出网络请求并在其上更快的构建网络层组件并提供合理的接口。
网友评论