详细使用方法见文章:
一. 概述
我们今天是来深入研究一下这个与我们日常开发密切相关的框架是如何实现的。
这是我对 AFNetworking 整个架构的理解,随后一系列的文章也会逐步分析这些模块。
在这篇文章中,我们有两个问题需要了解:
- 如何使用 NSURLSession 发出 HTTP 请求
- 如何使用 AFNetworking 发出 HTTP 请求
NSURLSession
NSURLSession
NSURLSession
- 实例化一个
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
<!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);
}];
注意:在 iOS9 中,苹果默认全局 HTTPs,如果你要发送不安全的 HTTP 请求,需要在 info.plist 中加入如下键值对才能发出不安全的 HTTP 请求
还有一件事情是要注意的是,AFNetworking 默认接收 json 格式的响应(因为这是在 iOS 平台上的框架,一般不需要 text/html),如果想要返回 html,需要设置 acceptableContentTypes
AFNetworking 的调用栈
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
AFHTTPSessionManager
- 有着自己的
AFHTTPRequestSerializer
- 和
AFJSONResponseSerializer
- 来管理请求和响应的序列化,同时依赖父类提供的接口保证安全、监控网络状态,实现发出 HTTP 请求这一核心功能
- GET:parameters:process:success:failure:
- [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
小结
NSURLSession
到这里,这一篇文章从上到下对 AFNetworking 是如何调用的进行了一个简单的概述,我会在随后的文章中会具体介绍 AFNetworking 中的每一个模块,了解它们是如何工作,并且如何合理地组织到一起的。
二. AFNetworking框架使用方法
AFNetworking文件夹导入工程;
2.添加类库:Security.framework, MobileCoreServices.framework, SystemConfiguration.framework ;
3. 在使用的类中或者直接在pch预编译文件内引入:#import "AFNetworking,h"
解决编译时警告:
Prefix.pch文件中加入
#import <SystemConfiguration/SystemConfiguration.h>
#import <MobileCoreServices/MobileCoreServices.h>
注:AFNetWorking使用了ARC ,在不使用ARC项目中使用时,对AFNetWorking的所有.m文件添加“-fobjc-arc”
在使用ARC项目中,使用“不使用ARC”的类库时,对类库的.m文件添加“-fno-objc-arc”