白水

iOS 框架注解—「AFHTTPSessionManager HTTP网络通信核心」

引导


AFNetWorking 基本是 iOS 开发中使用网络通信框架的标配,这个框架本身比较庞大,也很复杂,但是使用起来非常非常简单。

SourceCodeToolsClassPublic-Codeidea

本篇文章主要从【AFHTTPSessionManager HTTP网络通信核心】学习总结,该模块学习将续更 ~
在「时间 & 知识 」有限内,总结的文章难免有「未全、不足 」的地方,还望各位好友指出,可留言指正或是补充,以提高文章质量@CoderLN著;

Source Code【源码学习】


按照顺序还是先看 .h 文件

1
2
3
4
/**
`AFHTTPSessionManager` is a subclass of `AFURLSessionManager` with convenience methods
for making HTTP requests. When a `baseURL` is provided, requests made with
the `GET` / `POST` / et al. convenience methods can be made with relative paths.

注释中写到 AFHTTPSessionManagerAFURLSessionManager 的子类,并且带有方便的 HTTP 请求方法。当一个 baseURL 被提供,通过相对路径可以进行 get、post、put、patch、delete 五种不同的请求。
并且 AFN 鼓励我们在 AFHTTPSessionManager 再进行一次封装来满足我们自己的业务需求。


1
2
3
4
5
6
7
8
/**
The URL used to construct requests from relative paths in methods like
`requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods.
*/
注释:baseURL 用于构建请求,在方法中的相对路径,
比如方法`requestWithMethod:URLString:parameters:`和get,post这些遍历方法。
注意:暴露出的 baseUrl 属性是 readonly
@property (readonly, nonatomic, strong, nullable) NSURL *baseURL;

当我们在进行进一步封装的时候,可以将 baseURL 写成你自己的 HTTP 请求原始地址,比如

1
2
3
+ (NSURL *)baseURL {
return [NSURL URLWithString:kBaseURLString];
}

这里在对 baseURL 进行拼接的时候,也需要注意一下几点,防止出现 请求URL出现问题。示例如下

1
2
3
4
5
6
7
8
9
10
11
12
NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];
[NSURL URLWithString:@"foo" relativeToURL:baseURL];-->// http://example.com/v1/foo

[NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL];-->// http://example.com/v1/foo?bar=baz

[NSURL URLWithString:@"/foo" relativeToURL:baseURL];-->// http://example.com/foo

[NSURL URLWithString:@"foo/" relativeToURL:baseURL];-->// http://example.com/v1/foo

[NSURL URLWithString:@"/foo/" relativeToURL:baseURL];-->// http://example.com/foo/

[NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL];-->// http://example2.com/


1
2
3
4
// 请求序列化
@property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer;
// 响应序列化
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;

@name Initialization【初始化】

1
2
3
4
5
6
7
+ (instancetype)manager;

- (instancetype)initWithBaseURL:(nullable NSURL *)url;

- (instancetype)initWithBaseURL:(nullable NSURL *)url
sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration
NS_DESIGNATED_INITIALIZER;

这里暴露了三个初始化方法。第一个是类方法,后两个是需要传参的实例方法。
注意:NS_DESIGNATED_INITIALIZER
这个意思是 ?
它是表明该类有多种初始化的方法,在加上这个标记后,在系统的init方法里面一定要调用该方法
这个作用是 ?
指定的构造器通过发送初始化消息到父类来保证object被完全初始化,指定构造器有以下几个规则:

  • 指定构造器必须调用父类的指定构造器

  • 任何一个便利构造器必须调用最终指向指定构造器的其他构造器

  • 具有指定构造器的类必须实现父类的所有指定构造器

@name Making HTTP Requests【HTTP请求】

剩下的方法都是暴露出的 HTTP 相应请求方式的实例方法。若 HTTP 连接请求方式为 GET ,则调用相应的方法,并只需传入接口名称的字符串和请求参数,即可在 block 回调中获得请求结果。
下面列举一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 2.发送GET请求
/**
GET: NSString类型的请求路径,AFN内部会自动将该路径包装为一个url并创建请求对象
parameters: 请求参数,以字典的方式传递,AFN内部会判断当前是POST请求还是GET请求,
以选择直接拼接还是转换为NSData放到请求体中传递.
progress: 进度回调,此处为nil
success: 请求成功之后回调Block
task: 请求任务、
responseObject: 响应体信息(内部已编码处理JSON->OC对象)
failure: 失败回调(error:错误信息)
task.response: 响应头
*/
- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(nullable id)parameters
progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

1
2
3
4
5
6
7
8
9
10
/**
注意:DEPRECATED_ATTRIBUTE
这个的字面意思就是这个API不建议开发者再使用了,再使用时,会出现编译警告
比如之前的get post等方法再次使用的时候就会报警告。
*/
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(nullable id)parameters
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
DEPRECATED_ATTRIBUTE;

最后看一下,POST、GET、PUT、PATCH、DELETE请求方法传参基本都是大同小异。

  • GET 请求是向服务端发起请求数据,用来获取或查询资源信息
  • POST 请求是向服务端发送数据的,用来更新资源信息,它可以改变数据的种类等资源
  • PUT 请求和POST请求很像,都是发送数据的,但是PUT请求不能改变数据的种类等资源,它只能修改内容
  • DELETE 请求就是用来删除某个资源的
  • PATCH 请求和PUT请求一样,也是用来进行数据更新的,它是HTTP verb推荐用于更新的
  • 在实际开发过程中,我们还是使用【GET 和 POST】请求是最多的。

接着我们看实现 AFHTTPSessionManager.m

首先看到的是定义了一个私有属性 baseUrl,
注意:与头文件中暴露给外部的 baseUrl 属性不同的,该属性前缀是 readwrite

1
2
3
4
/**
注意:与头文件中暴露给外部的 baseUrl 属性不同的,该属性前缀是 **readwrite**
*/
@property (readwrite, nonatomic, strong) NSURL *baseURL;

接着就可以看到有四个 init 初始化方法,这里只说 initWithBaseURL:sessionConfiguration: 所有初始化方法在内部都是直接或间接调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
全能初始化方法:在其中通过configuration生成了AFHTTPSessionManager的实例对象,
并初始化了 baseURL,requestSerializer,responseSerializer 属性
注意:session manager的对象是调用父类 AFURLSessionManager 的 initWithSessionConfiguration: 方法生成的,
所以要研究下父类AFURLSessionManager
*/
- (instancetype)initWithBaseURL:(NSURL *)url
sessionConfiguration:(NSURLSessionConfiguration *)configuration
{
self = [super initWithSessionConfiguration:configuration];
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:@"/"]) {
url = [url URLByAppendingPathComponent:@""];
}

self.baseURL = url;

/*
请求序列化器和响应序列化器进行初始化。
请求序列化器是 AFHTTPRequestSerializer 类型,
响应序列化器是 AFJSONResponseSerializer 类型
*/
self.requestSerializer = [AFHTTPRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];

return self;
}

接下来,我们就来到了核心部分,HTTP请求方式对应的方法。可以看到这些方法内部其实都统一调用了一个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
1.先调用requestSerializer的实例方法requestWithMethod:方法生成请求request。若生成request时出现错误,则回调该错误。
2.将上面生成的request作为参数传入dataTaskWithRequest方法,生成dataTask实例对象
*/
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
{

}

补充:

1
2
3
4
5
6
7
8
9
10
/**
absoluteString 属性可以将NSUR转换为NSString;
而下面两个方法却是NSURL的初始化方法,将NSString转换为NSURL了。
这几个方法涉及到NSURL和NSString的互相转换。
*/
@property (nullable, readonly, copy) NSString *absoluteString;

- (nullable instancetype)initWithString:(NSString *)URLString relativeToURL:(nullable NSURL *)baseURL NS_DESIGNATED_INITIALIZER;

+ (nullable instancetype)URLWithString:(NSString *)URLString relativeToURL:(nullable NSURL *)baseURL;

Reading


  • 如果在阅读过程中遇到 Error || New ideas,希望你能 issue 我,我会及时补充谢谢。
  • 熬夜写者不易,喜欢可 赞赏 or Star 一波;点击左上角关注 或 『Public:Codeidea』,在 Demo | 文章 | Rss 更新时收到提醒通知,便捷阅读。
既然阅读完了    就在下面留言吧!

标题:iOS 框架注解—「AFHTTPSessionManager HTTP网络通信核心」

作者:白水

链接:http://githubidea.github.io/SourceAnnotations/AFN3.0+SourceCode-AFHTTPSessionManager.html

版权声明: 署名-非商业性使用-禁止演绎 4.0 国际 本博客文章除特别声明外均为原创,如需转载请务必保留原链接(可点击进入的链接)和 作者出处。