iOS网络——AFNetworking AFHttpSessionManager源码解析
来源:互联网 发布:淘宝比价软件推荐 编辑:程序博客网 时间:2024/05/16 04:08
你要知道的NSURLSession都在这里
转载请注明出处 http://blog.csdn.net/u014205968/article/details/78481519
本系列文章主要讲解iOS中网络请求类NSURLSession的使用方法进行详解,同时也会以此为扩展,讲解SDWebImage中图片下载功能的源码分析,讲解AFNetworking相关源码分析。本系列文章主要分为以下几篇进行讲解,读者可按需查阅。
- iOS网络——NSURLSession详解及SDWebImage源码解析
- iOS网络——SDWebImage SDImageDownloader源码解析
- iOS网络——AFNetworking AFURLSessionManager源码解析
- iOS网络——AFNetworking AFHttpSessionManager源码解析
AFNetworking AFHTTPSessionManager源码解析
前一篇文章我们讲解了AFURLSessionManager
的源码,最后还给了一个只使用AFURLSessionManager
来创建NSURLSessionDataTask
和NSURLSessionDownloadTask
的栗子,但是发现创建下载任务真的很简单了,只需要传入要下载文件的NSURL对象
,在传入几个回调块就能将文件下载到指定的目录中,并且可以监控下载进度,真的很方便,但NSURLSessionDataTask
创建的任务默认是GET
请求,如果需要其他如POST
请求还需要修改request
就显得有些麻烦了,今天要介绍的AFHTTPSessionManager
就是继承自AFURLSessionManager
,通过名称就知道这个类为HTTP
访问提供了更加便捷的方法。
直接看头文件的声明源码:
//继承自AFURLSessionManager类@interface AFHTTPSessionManager : AFURLSessionManager <NSSecureCoding, NSCopying>//网络请求要访问的URL@property (readonly, nonatomic, strong, nullable) NSURL *baseURL;//请求序列化@property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer;//响应序列化@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;///-------------------------------/// @name Managing Security Policy///-------------------------------//安全策略@property (nonatomic, strong) AFSecurityPolicy *securityPolicy;///---------------------/// @name Initialization///---------------------//类方法返回一个AFHTTPSessionManager对象,不是单例,每次调用都重新创建+ (instancetype)manager;//构造函数- (instancetype)initWithBaseURL:(nullable NSURL *)url;//构造函数- (instancetype)initWithBaseURL:(nullable NSURL *)url sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER;///---------------------------/// @name Making HTTP Requests///---------------------------//获取一个GET请求- (nullable NSURLSessionDataTask *)GET:(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;//获取一个GET请求- (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;//获取一个HEAD请求- (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;//获取一个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请求- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;//获取一个POST请求- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;//获取一个POST请求- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;//获取一个PUT请求- (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;//获取一个PATCH请求- (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;//获取一个DELETE请求- (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;@end
AFHTTPSessionManager
提供了一系列的构造方法以及HTTP访问的方法。
@interface AFHTTPSessionManager ()@property (readwrite, nonatomic, strong) NSURL *baseURL;@end@implementation AFHTTPSessionManager@dynamic responseSerializer;//类方法,返回一个新创建的AFHTTPSessionManager对象+ (instancetype)manager { return [[[self class] alloc] initWithBaseURL:nil];}//构造函数- (instancetype)init { return [self initWithBaseURL:nil];}//构造函数- (instancetype)initWithBaseURL:(NSURL *)url { return [self initWithBaseURL:url sessionConfiguration:nil];}//构造函数- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { return [self initWithBaseURL:nil sessionConfiguration:configuration];}//构造函数- (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; //获取单例的请求序列化和响应序列化器 self.requestSerializer = [AFHTTPRequestSerializer serializer]; self.responseSerializer = [AFJSONResponseSerializer serializer]; return self;}#pragma mark -//setter- (void)setRequestSerializer:(AFHTTPRequestSerializer <AFURLRequestSerialization> *)requestSerializer { NSParameterAssert(requestSerializer); _requestSerializer = requestSerializer;}//setter- (void)setResponseSerializer:(AFHTTPResponseSerializer <AFURLResponseSerialization> *)responseSerializer { NSParameterAssert(responseSerializer); [super setResponseSerializer:responseSerializer];}@dynamic securityPolicy;//setter设置安全策略- (void)setSecurityPolicy:(AFSecurityPolicy *)securityPolicy { if (securityPolicy.SSLPinningMode != AFSSLPinningModeNone && ![self.baseURL.scheme isEqualToString:@"https"]) { NSString *pinningMode = @"Unknown Pinning Mode"; switch (securityPolicy.SSLPinningMode) { case AFSSLPinningModeNone: pinningMode = @"AFSSLPinningModeNone"; break; case AFSSLPinningModeCertificate: pinningMode = @"AFSSLPinningModeCertificate"; break; case AFSSLPinningModePublicKey: pinningMode = @"AFSSLPinningModePublicKey"; break; } NSString *reason = [NSString stringWithFormat:@"A security policy configured with `%@` can only be applied on a manager with a secure base URL (i.e. https)", pinningMode]; @throw [NSException exceptionWithName:@"Invalid Security Policy" reason:reason userInfo:nil]; } [super setSecurityPolicy:securityPolicy];}
上面的方法就是一系列构造函数,用于初始化父类对象以及序列化器,设置安全策略等,没有太多复杂的内容。
//GET请求,调用下面那个方法- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{ return [self GET:URLString parameters:parameters progress:nil success:success failure:failure];}//GET请求- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))downloadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure{ //调用另一个方法构造GET请求 NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:downloadProgress success:success failure:failure]; /* 启动任务 使用AFHTTPSessionManager创建的任务默认都帮你启动了,所以不需要手动调用resume方法了 上一篇中讲解的AFURLSessionManager默认没有启动,所以获取任务后要手动启动 */ [dataTask resume]; return dataTask;}//获取HEAD请求- (NSURLSessionDataTask *)HEAD:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{ //同样调用下面的一个方法来获取 NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) { if (success) { success(task); } } failure:failure]; //默认启动任务 [dataTask resume]; return dataTask;}//获取POST请求- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{ //调用下面的方法获取 return [self POST:URLString parameters:parameters progress:nil success:success failure:failure];}//获取POST请求- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))uploadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure{ //同GET HEAD方法一样,调用一个方法获取任务 NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure]; //默认启动任务 [dataTask resume]; return dataTask;}//获取POST上传文件请求- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id<AFMultipartFormData> _Nonnull))block success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure{ //调用下面的方法来构造上传文件的POST请求 return [self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure];}//上传文件POST请求- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{ //构造一个request请求 NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError]; //如果在做序列化时出错在主线程调用failure回调块 if (serializationError) { if (failure) { dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); } return nil; } //调用父类的方法获取一个上传的任务 __block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:uploadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { if (error) { if (failure) { failure(task, error); } } else { if (success) { success(task, responseObject); } } }]; //默认启动任务 [task resume]; return task;}//获取PUT请求- (NSURLSessionDataTask *)PUT:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{ //通过一个通用的方法来获取dataTask NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; //默认启动任务 [dataTask resume]; return dataTask;}//同上- (NSURLSessionDataTask *)PATCH:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{ NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; [dataTask resume]; return dataTask;}//同上- (NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{ NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; [dataTask resume]; return dataTask;}//一个通用的方法来构造NSURLSessionDataTask- (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{ //通过请求序列化器构造一个request请求 //需要传入请求方法GET POST DELETE PUT这样的字符串 以及相关参数 NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]; //如果序列化失败在主线程中执行failure回调块 if (serializationError) { if (failure) { dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); } return nil; } //序列化成功,调用父类的方法获取dataTask __block NSURLSessionDataTask *dataTask = nil; dataTask = [self dataTaskWithRequest:request uploadProgress:uploadProgress downloadProgress:downloadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { if (error) { if (failure) { failure(dataTask, error); } } else { if (success) { success(dataTask, responseObject); } } }]; //返回dataTask return dataTask;}
上面的代码也很简单,是在AFURLSessionManager
之上做了一些处理,其中涉及的AFURLRequestSerialization
和AFURLResponseSerialization
由于不是本系列文章的关注点所以没有相关讲解,有需要的读者请自行查阅。
AFHTTPSessionManager
继承自AFURLSessionManager
并提供了更加便捷的网络请求接口,如果阅读了前一篇AFURLSessionManager
可以发现它才是重点。AFHTTPSessionManager
只是在它的基础上做了一些简单的封装,提供了更加便捷的接口。
通过AFURLSessionManager
和AFHTTPSessionManager
源码的阅读可以学习到AFNetworking
在代码设计方面的优点,以及对NSURLSession
的使用更清晰了。
备注
由于作者水平有限,难免出现纰漏,如有问题还请不吝赐教。
- iOS网络——AFNetworking AFHttpSessionManager源码解析
- iOS网络——AFNetworking AFURLSessionManager源码解析
- AFNetworking源码 - AFHTTPSessionManager
- iOS源码解析—AFNetworking(RequestSerializer)
- iOS源码解析—AFNetworking(ResponseSerializer)
- iOS源码解析—AFNetworking(URLSession)
- iOS源码解析—AFNetworking(AFSecurityPolicy)
- iOS源码解析—AFNetworking(AFNetworkReachabilityManager)
- AFNetworking 3.0 源码解读(六)之 AFHTTPSessionManager
- iOS 【network-封装业务类AFNetworking(AFHTTPSessionManager)】
- iOS网络——NSURLSession详解及SDWebImage源码解析
- iOS网络——SDWebImage SDImageDownloader源码解析
- AFNetworking源码解析<三>
- AFNetworking源码解析<三>
- AFNetworking源码解析<三>
- AFNetworking源码解析<四>
- AFNetworking源码解析<四>
- AFNetworking源码解析https
- mysql分区及实例演示
- Linux 习题6
- 总结篇---闭包问题从此再不难
- bzoj 2005 [Noi2010]能量采集 O(n)莫比乌斯反演
- Tomcat相关整理
- iOS网络——AFNetworking AFHttpSessionManager源码解析
- iOS中Label的首行缩进
- 论文笔记-An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application
- 索引
- php扩展开发---使用PHP Embed SAPI实现Opcodes查看器
- Spring Cloud学习--配置中心(Config)
- 了解大数据
- 去除字符串所有换行和空格,字符串添加%
- 欢迎使用CSDN-markdown编辑器