AFNetworking 2.0获取响应头信息

转载请注明出处:

前文有提到在初始化的时候可以设置Http的头信息,这没有任何问题,但是在笔者使用过程中,时常是要获取Http返回的一些头信息,在初次用AFNetworking2.0新特性NSURLSessionDataTask的时候,为了获取返回的头信息,搞了两个晚上,先是度娘,谷歌,StackOverflow,然后各种那个群找人,嘴壶问同事找大神,最后都说没有用过。就在想要放弃,想跟服务端沟通,不要把必要信息放在头信息中得时候,忽然灵感忽现:

再此讲述一下解决过程和最后的解决方法。

用过AFNetworking2.0 中NSURLSessionDataTask的朋友都知道,大概一个请求方式会类似于下面的方法(由于代码是从程序中直接拷出来的,所有直接使用会报错,请见谅)

– (NSURLSessionDataTask *)requestUpdateScheduleWithParam:(NSArray *)paramsuccess:(void (^)(NSString *))successfailure:(void (^)(NSString *))failure{NSError *parseError = nil;//NSDictionary转换为DataNSData* jsonData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&parseError];//Data转换为JSONNSString* str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];NSDictionary *dic = @{@"param": str};NSURLSessionDataTask *task = [self POST:UpdateScheduleRequest parameters:dic success:^(NSURLSessionDataTask *task, id responseObject) {NSInteger result = [responseObject[@"result"] integerValue];if ( result == 0 ) {success(@"true");} else {NSString *message = responseObject[@"message"];failure(message);}} failure:^(NSURLSessionDataTask *task, NSError *error) {DLog(@"%@",error.localizedDescription);failure(error.localizedDescription);}];return task;}在返回的结果中我们能够取到的返回数据只有三种:

1、NSURLSessionDataTask *task 返回的和此次请求有关的描述

2、id responseObject AFNetworking帮助自动格式化后的结果,,与上文初始化HttpClient时默认的responseSerializer对应

3、NSError *error AFNetworking内部报错,网络请求不通的或者数据解析错误等

上面所描述的三种数据中 responseObject和error显然是不可行的,所以只有在task中寻找希望,所以详细查看类NSURLSessionDataTask

发现其中只是简单继承于 NSURLSessionTask,于是继续进入NSURLSessionTask观察:

会看到其中有个属性:

@property (readonly, copy) NSURLResponse *response;/* may be nil if no response has been received */这个似乎很接近我们需要的结果,因为往往response中都会包含我们所需要的头信息。然后继续往下查看NSURLResponse的信息。

结果在其中只有寥寥数条属性,关键的是没有我们想要的Header信息(代码篇幅略长,所以删除了一些注释)!

@interface NSURLResponse : NSObject <NSSecureCoding, NSCopying>{@packageNSURLResponseInternal *_internal;}/*!@method initWithURL:MIMEType:expectedContentLength:textEncodingName:@abstract Initialize an NSURLResponse with the provided values.@param URL the URL@param MIMETYPE the MIME content type of the response@param expectedContentLength the expected content length of the associated data@param textEncodingName the name of the text encoding for the associated data, if applicable, else nil@result The initialized NSURLResponse.@discussion This is the designated initializer for NSURLResponse.*/- (instancetype)initWithURL:(NSURL *)URL MIMEType:(NSString *)MIMEType expectedContentLength:(NSInteger)length textEncodingName:(NSString *)name;@property (readonly, copy) NSURL *URL;@property (readonly, copy) NSString *MIMEType;@property (readonly) long long expectedContentLength;@property (readonly, copy) NSString *textEncodingName;@property (readonly, copy) NSString *suggestedFilename;@end这可如何是好!!!希望似乎就此破灭,仿佛看到服务端的大哥大姐投来的鄙视的眼神于吐槽(#¥%#¥……%……¥#@¥#@%¥#……此处省略数万字)

但是!在NSURLResponse中继续往下看,可以看到NSURLResponse的一个子类NSHTTPURLResponse,在这个子类中竟然有看着很像的的一个属性。

/*!@method allHeaderFields@abstract Returns a dictionary containing all the HTTP header fieldsof the receiver.@discussion By examining this header dictionary, clients can seethe "raw" header information which was reported to the protocolimplementation by the HTTP server. This may be of use tosophisticated or special-purpose HTTP clients.@result A dictionary containing all the HTTP header fields of thereceiver.*/@property (readonly, copy) NSDictionary *allHeaderFields;恩,对,这个属性看起来基友可能(因为在使用AFHTTPRequestOperation请求数据的时候,其中也有个NSHTTPURLResponse,同样的也是在allHeaderFields中取到头信息)

但是在NSURLSessionTask中只有NSURLResponse *response而没有NSHTTPURLResponse *response!父类又不能使用子类中得属性。再次开始纠结!

结果抱着试试看的心理将NSURLResponse *response强制转换成NSHTTPURLResponse,结果TMD竟然可以!

– (NSURLSessionDataTask *)requestLoginWithUsername:(NSString *)usernamepassword:(NSString *)passwordsuccess:(void (^)(NSString *,LoginDetailsDataModel *))successfailure:(void (^)(NSString *))failure{NSDictionary *dic = @{@"username": username, @"password":[self md5:password]};NSURLSessionDataTask *task = [self GET:LoginRequest parameters:dic success:^(NSURLSessionDataTask *task, id responseObject) {LoginDataModel *loginSuccessDataModel = [[LoginDataModel alloc] initWithDictionary:responseObject];NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response; <span style="color:#FF0000;">// 此处强制转换类型。</span>NSInteger result = [loginSuccessDataModel.result integerValue];if ( result == 0 ) {success(response.allHeaderFields[@"sid"],loginSuccessDataModel.userInfo);} else {NSString *message = loginSuccessDataModel.message;DLog(@"%@",message);failure(message);}} failure:^(NSURLSessionDataTask *task, NSError *error) {DLog(@"%@",error.localizedDescription);failure(error.localizedDescription);}];return task;}最后问题解决。

这似乎是NSURLSessionDataTask本身的一个问题,希望以后可以得到解决。

可是旅行的彼时那刻我的心情一直是好的吗?

AFNetworking 2.0获取响应头信息

相关文章:

你感兴趣的文章:

标签云: