**放在最前:文章为本人学习随笔,若对您有帮助,不胜荣幸;若有错漏欢迎评论区留言。**
一、框架解析
使用AFNetWorking 也已经几年了,使用起来也顺手,但是最值得我们学习的AFN 结构设计思想,仍然是要努力探究的方向。先让我们来学习下AFN的整体结构是怎样的吧,见图思义:
1、AFHTTPSessionManager
负责发送网络请求及相应的处理,其调用栈如下:
- [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 的请求回调,我们再调用 - resume 方法执行请求,并在事件执行时通知代理 AFURLSessionManagerTaskDelegate
如上简单一个GET请求示例如下:
[[AFAppDotNetAPIClient sharedClient] GET:@"stream/0/posts/stream/global" parameters:nil progress:nil success:^(NSURLSessionDataTask * __unused task, id JSON) {
NSArray *postsFromResponse = [JSON valueForKeyPath:@"data"]; NSMutableArray *mutablePosts = [NSMutableArray arrayWithCapacity:[postsFromResponse count]];
for (NSDictionary *attributes in postsFromResponse) {
Post *post = [[Post alloc] initWithAttributes:attributes];
[mutablePosts addObject:post]; }
if (block) {
block([NSArray arrayWithArray:mutablePosts], nil);
}
} failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
if (block) {
block([NSArray array], error);
} }];
2、AFNetworkReachabilityManager:
实时监测网络状态的工具类,另系统自带Reachability 也可
3、AFSecurityPolicy :
网络安全的工具类,主要针对HTTPS服务;
typedef NS_ENUM(NSUInteger,AFSSLPinningMode){ AFSSLPinningModeNone, AFSSLPinningModePublicKey, AFSSLPinningModeCertificate};
主要根据 AFSSLPinningMode 设置https请求验证类型,验证底层为系统Security框架;
4、AFURLRequestSerialization:
序列化工具类,封装NSMutableRequest,上传的数据转换成JSON格式
5、AFURLResponseSerialization:
AFURLResponseSerialization主要负责对网络请求回来的响应报文数据进行反序列化
下面是AFHTTPResponseSerializer的相关属性:
@interface AFHTTPResponseSerializer : NSObject @property (nonatomic, assign) NSStringEncoding stringEncoding; //文本编码@property (nonatomic, copy, nullable) NSIndexSet *acceptableStatusCodes; //允许的http状态码 @property (nonatomic, copy, nullable) NSSet *acceptableContentTypes; //允许的content-type类型@end
stringEncoding属性是文本编码方式,用于响应的报文数据反序列化成字符串。acceptableStatusCodes是一个集合,表示客户端可以接受的报文数据的http状态码。acceptableContentTypes是一个集合,表示客户端可以接受的报文数据的content-type类型。
自带的各个解析器
以下解析器都集成自AFHTTPResponseSerializer 的子类不同类型对应不同的解析方法,主要方法:
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing*)error
AFJSONResponseSerializer
acceptTypes:
[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];
主要方法:
[NSJSONSerializationJSONObjectWithData:dataoptions:self.readingOptionserror:&serializationError]
AFXMLParserResponseSerializer
acceptTypes:
[[NSSet alloc] initWithObjects:@"application/xml",@"text/xml",nil];
主要方法:
[[NSXMLParser alloc] initWithData:data]
AFXMLDocumentResponseSerializer
acceptTypes:
[[NSSet alloc] initWithObjects:@"application/xml",@"text/xml",nil];
主要方法:
[[NSXMLDocument alloc] initWithData:data options:self.options error:&serializationError];
AFPropertyListResponseSerializer
acceptTypes:
[[NSSet alloc] initWithObjects:@"application/x-plist", nil];
主要方法:
[NSPropertyListSerialization propertyListWithData:data options:self.readOptions format:NULL error:&serializationError];
AFImageResponseSerializer
acceptTypes:
[[NSSet alloc] initWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil];
主要方法:
CoreGraphics框架下 CGImageRefimageRef 、GDataProviderRef
AFCompoundResponseSerializer
混合解析器,初始化方法如下
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers {
AFCompoundResponseSerializer *serializer = [[self alloc] init];
serializer.responseSerializers= responseSerializers;
return serializer;
}
7、UIKit分类
常用分类 有
UIButton+AFNetworking 、 UIImageView+AFNetworking、UIImage+AFNetworking
二、基本使用
1、POST/GET/DELETE/PATCH/PUT/Download/Upload
1)初始化设置相关
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; [configuration setTLSMinimumSupportedProtocol:kTLSProtocol12]; //协议类型 manager=[manager initWithBaseURL:[NSURL URLWithString:urlString] sessionConfiguration:configuration]; //设置证书策略 NSData *certData = [NSData dataWithContentsOfFile:cerPath]; securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; //AFSSLPinningModeNone //validatesDomainName 是否需要验证域名,默认为YES; securityPolicy.validatesDomainName = YES; securityPolicy.pinnedCertificates = [[NSSet alloc] initWithObjects:certData,nil]; //禁用http响应缓存 manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData; [manager setDataTaskWillCacheResponseBlock:nil];
2) 序列化
manager.requestSerializer = [AFJSONRequestSerializer serializer]; manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes =[NSSet setWithObjects:@"application/json",@"application/octet-stream",@"text/plain",@"multipart/form-data",@"text/html,@"text/json", nil];
//语言化设置 [manager.requestSerializersetValue:languageCodeforHTTPHeaderField:@"lang"];
//超时设置
[manager.requestSerializer setTimeoutInterval:self.requestTimeoutInterval];
3、断点续传
断点续传,主要是预先创建好一个空文件,然后边写边提交或下载并且记好最后位置即可;具体可见参考4;
三、图片下载管理机制
AFN 提供了完整的图片下载及缓存机制,
1、AFImageDownloader : 图片下载器,主要通过 AFImageDownloaderMergedTask 类管理下载任务
2、AFAutoPurgingImageCache:图片缓存 ,主要是根据id去写入和取出,写入是通过串行队列和栅栏加锁的形式防止写入的安全性问题。
参考:
1、AFNetworking 概述:https://draveness.me/afnetworking1/
2、AFNetworking 3.1.0 源码解读:https://www.jianshu.com/p/c36159094e24
3、 iOS源码解析—AFNetworking(ResponseSerializer) - 简书