AFNetworking 2.0获取响应头信息

转载请注明出处:http://blog.csdn.net/dengbin9009/article/details/43304813

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

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

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

- (NSURLSessionDataTask *)requestUpdateScheduleWithParam:(NSArray *)param
                                                 success:(void (^)(NSString *))success
                                                 failure:(void (^)(NSString *))failure{

    NSError *parseError = nil;
    //NSDictionary转换为Data
    NSData* jsonData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&parseError];
    //Data转换为JSON
    NSString* 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>
{
    @package
    NSURLResponseInternal *_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 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;

恩,对,这个属性看起来基友可能(因为在使用AFHTTPRequestOperation请求数据的时候,其中也有个NSHTTPURLResponse,同样的也是在allHeaderFields中取到头信息)

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

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

- (NSURLSessionDataTask *)requestLoginWithUsername:(NSString *)username
                                          password:(NSString *)password
                                           success:(void (^)(NSString *,LoginDetailsDataModel *))success
                                           failure:(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本身的一个问题,希望以后可以得到解决。

时间: 2024-12-29 23:23:40

AFNetworking 2.0获取响应头信息的相关文章

wget/curl查看请求响应头信息

wget / curl 是两个比较方便的测试http功能的命令行工具,大多数情况下,测试http功能主要是查看请求响应 头信息 ,而给这两个工具加上适当的命令行参数即可轻易做到,其实查man手册就能找到对应的参数选项,不过这里仍然mark一下. wget --debug Turn on debug output, meaning various information important to the developers of Wget if it does not work properly

PHP获取http头信息和CI中获取HTTP头信息的方法

CI中获取HTTP头信息的方法: $this->input->request_headers() 在不支持apache_request_headers()的非Apache环境非常有用.返回请求头(header)数组. $headers = $this->input->request_headers(); ------------------------------------------------------------------------------------------

http响应头信息

HTTP 响应头信息 HTTP请求头提供了关于请求,响应或者其他的发送实体的信息. 在本章节中我们将具体来介绍HTTP响应头信息. 应答头 说明 Allow 服务器支持哪些请求方法(如GET.POST等). Content-Encoding 文档的编码(Encode)方法.只有在解码之后才可以得到Content-Type头指定的内容类型.利用gzip压缩文档能够显著地减少HTML文档的下载时间.Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netsca

HTTP 响应头信息

HTTP 响应头信息 HTTP请求头提供了关于请求,响应或者其他的发送实体的信息. 在本章节中我们将具体来介绍HTTP响应头信息.

curl/wget 测试http请求的响应头信息

1. wget –debug wget可以使用debug信息来查看信息头,如下: [[email protected] ~]# wget --debug http://192.168.112.129/index.html DEBUG output created by Wget 1.12 on linux-gnu. --2017-06-01 10:15:12--  http://192.168.112.129/index.html Connecting to 192.168.112.129:80

PHP获取http头信息

// 获取全部 HTTP 请求头信息---函数仅适用于 Apache 也可使用 别名 apache_request_headers() $is_headers = function_exists('getallheaders'); $headers=array(); if(!isset($is_headers)) #如果是nginx { foreach ($_SERVER as $key => $value) { if ('HTTP_' == substr($key, 0, 5)) { $hea

视图函数获取请求头信息

视图函数获取相关信息请求头信息 Django 的request 中封装的了所有的信息,之前我们只是使用了POST,GET的方法来获取数据 查看request类 def index(request): print(type(request)) return HttpResponse('ko') #输出 <class 'django.core.handlers.wsgi.WSGIRequest'> 导入这个类看看有什么方法 def index (request): from django.core

Magicodes.WeiChat——使用OAuth 2.0获取微信用户信息

使用Magicodes.WeiChat,可以很方便的获取到微信用户的信息.在使用OAuth 2.0之前,你先需要做以下操作: 1)在开发者中心修改[网页授权获取用户基本信息],在弹出的界面输入自己的根域名.比如:weichat.chinacloudsites.cn 如下图所示: 2)配置菜单或者链接(如果使用特性“WeChatOAuth”,本步骤可以略过,这里只是介绍下原理,具体请参考步骤3的说明).Magicodes.WeiChat在控制器WeiChatController中进行处理,配置路径

Tomcat 中响应头信息(Http Response Header) Content-Length 和 Transfer-Encoding

户端(PC浏览器或者手机浏览器)在接受到Tomcat的响应的时候,头信息通常都会带上Content-Length ,一般情况下客户端会在接受完Content-Length长度的数据之后才会开始解析.而在Tomcat上,页面处理过程中会将需要out.print的数据都放在缓存中,然后一次性的返回给客户端. 另外一种情况就是头信息中不存在Content-Length ,取而代之的是Tansfer-Encoding:chunked ,这个头信息的的意思是response的内容会被Tomcat分成一块一