一直都是在给服务器端发送请求的时候可能会出现设置头文件的情况,但这次获取HTTP 返回的头文件,着实让我纠结一番,但最终还是实现了,总结一下。(PS:其实最后方法很简单,只是分享一下纠结过程)
先看一下使用 AFNetworking3.0是如何获取数据的。
AFHTTPSessionManager *httpsManager = [AFHTTPSessionManager manager];
httpsManager.requestSerializer = [AFHTTPRequestSerializer serializer];
httpsManager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFSecurityPolicy *security = [AFSecurityPolicy defaultPolicy];
security.allowInvalidCertificates = YES;
security.validatesDomainName = NO;
httpsManager.securityPolicy = security;
[httpsManager POST:ZCFormatURL(@"/paydone") parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
添加头文件:
[httpsManager.requestSerializer setValue:@"iOS" forHTTPHeaderField:@"os_type"];
[httpsManager.requestSerializer setValue:[info getNowTime] forHTTPHeaderField:@"time"];
分析一下返回的数据
failure 时:
- NSURLSessionDataTask * _Nullable task 和请求有关的一些描述
- NSError * _Nonnull error 网络请求不通等错误描述
success 时: - NSURLSessionDataTask * _Nonnull task 和请求有关的一些描述
- id _Nullable responseObject AFNetworking格式化之后的结果,与AFHTTPSessionManager的responseSerializer相对应
很明显,我们所要的数据最有可能是在 task 中,所以那就看一下NSURLSessionDataTask
类吧,
/*
* An NSURLSessionDataTask does not provide any additional
* functionality over an NSURLSessionTask and its presence is merely
* to provide lexical differentiation from download and upload tasks.
*/
@interface NSURLSessionDataTask : NSURLSessionTask
@end
发现它仅仅只是继承自NSURLSessionTask
,并没有自己的属性方法,好,那就接着看父类NSURLSessionTask
父类属性倒是不少(太长了,代码不放这了)。最有可能包含我们所要信息应该就是response属性了
@property (nullable, readonly, copy) NSURLResponse *response; /* may be nil if no response has been received */
好,那就接着看NSURLResponse
,发现他的属性方法中没有能获取头文件的。倒是他的子类中有一个属性挺顺眼的。
/*!
@method allHeaderFields
@abstract Returns a dictionary containing all the HTTP header fields
of the receiver.
@discussion By examining this header dictionary, clients can see
the "raw" header information which was reported to the protocol
implementation by the HTTP server. This may be of use to
sophisticated or special-purpose HTTP clients.
@result A dictionary containing all the HTTP header fields of the
receiver.
*/
@property (readonly, copy) NSDictionary *allHeaderFields;
赶紧回去判定一下返回的task.response是不是NSURLResponse的子类
if ([task.response isKindOfClass:[NSHTTPURLResponse class]]) {
NSLog(@"The return class is subclass %@",NSStringFromClass([NSHTTPURLResponse class]));
}else{
NSLog(@"The return class is not subclass %@",NSStringFromClass([NSHTTPURLResponse class]));
}
打印日志:
2016-01-15 11:29:52.547 demo[535:106586] The return class is subclass NSHTTPURLResponse
果真是,这下就好办多了,直接强转,获取数据就好了
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
NSDictionary *allHeaders = response.allHeaderFields;