【问题标题】:AFNetworking 2.0 // How to read response headerAFNetworking 2.0 // 如何读取响应头
【发布时间】:2013-12-23 15:14:11
【问题描述】:

我正在使用新版本的 AFNetworking,但我不知道如何读取响应的标头。 我正在使用 AFHTTPSessionManager 执行我的查询,一切正常,但我无法找到标题响应字段。

我是这样处理的

self.sessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:BASE_URL]];
[self.sessionManager GET:urlId parameters:nil
    success:^(NSURLSessionDataTask *task, id responseObject) {
        if ([self.delegate respondsToSelector:@selector(userIsLoadedWithInfos:)]) {
            [self.delegate userIsLoadedWithInfos: responseObject];
        }
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        if ([self.delegate respondsToSelector:@selector(userLoadingFailed)]) {
            [self.delegate userLoadingFailed];
        }
    }
];

我试图读取任务的响应属性,但它返回一个不包含标题的 NSURLResponse。

现在有人如何读取 2.0 版本的响应标头吗?

【问题讨论】:

    标签: ios objective-c cocoa-touch ios7 afnetworking-2


    【解决方案1】:

    您是否尝试过从返回的 NSURLResponse 获取标头,

    您可以尝试使用 NSURLResponse 对象,

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
    if ([httpResponse respondsToSelector:@selector(allHeaderFields)]) {
        NSDictionary *dictionary = [httpResponse allHeaderFields];
        NSLog([dictionary description]);
    }
    

    希望对您有所帮助!

    【讨论】:

    • 我已经尝试过了,但似乎 NSURLResponse 不包含 allHeaderFields 方法。只有 NSHTTPURLResponse 类包含它
    • @MtotheK:检查更新的答案,将您的回复转换为 NSHTTPURLResponse。
    • @Virussmca:请不要调用转换转换。这是误导。
    • 我试过这个完全相同的东西,它正在工作,所以你的答案是正确的,谢谢你的帮助!
    • 你的强制转换和选择器检查的顺序实际上是错误的:如果它响应allHeaderFields,你就知道你可以安全地强制转换到一个有这个方法的类
    【解决方案2】:

    我将AFHTTPRequestOperationManager 子类化并使用:

    - (AFHTTPRequestOperation *)POST:(NSString *)URLString
                          parameters:(NSDictionary *)parameters
                             success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                             failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
    

    我的大多数网络服务请求的方法。使用该方法时,响应标头将成为操作对象的一部分。像这样的:

    [self POST:url parameters:newParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
        // Response headers will be a dictionary
        NSDictionary *headers = operation.response.allHeaderFields;
    ...
    

    【讨论】:

      【解决方案3】:

      比 Viruss mcs 的代码更健壮:

      if ([task.response isKindOfClass:[NSHTTPURLResponse class]]) {
          NSHTTPURLResponse *r = (NSHTTPURLResponse *)task.response;
          NSLog(@"%@" ,[r allHeaderFields]);
      }
      

      返回

      {
          Connection = "Keep-Alive";
          "Content-Length" = 12771;
          "Content-Type" = "application/json";
          Date = "Fri, 06 Dec 2013 10:40:48 GMT";
          "Keep-Alive" = "timeout=5";
          "Proxy-Connection" = "Keep-Alive";
          Server = "gunicorn/18.0";
      }
      

      同样,您可以确保使用 [response respondsToSelector:@selector(allHeaderFields)] 正确地进行转换,但您也应该在进行转换之前调用它

      if ([task.response respondsToSelector:@selector(allHeaderFields)]) {
          NSHTTPURLResponse *r = (NSHTTPURLResponse *)task.response;
          NSLog(@"%@" ,[r allHeaderFields]);
      }
      

      或根本没有演员表:

      if ([task.response respondsToSelector:@selector(allHeaderFields)]) {
          NSLog(@"%@" ,[task.response performSelector:@selector(allHeaderFields)]);
      }
      

      【讨论】:

        【解决方案4】:

        有趣的是,上面的响应表明参数id responseObject 返回一个NSURLResponse。我在后端运行 JAX-RS 服务器,但得到了不同的响应。当对我的服务器执行curl 命令时,我的响应是这样的:

        $ curl -v "http://10.0.1.8:3000/items"
        * About to connect() to 10.0.1.8 port 3000 (#0)
        *   Trying 10.0.1.8...
        * Adding handle: conn: 0x7f9f51804000
        * Adding handle: send: 0
        * Adding handle: recv: 0
        * Curl_addHandleToPipeline: length: 1
        * - Conn 0 (0x7f9f51804000) send_pipe: 1, recv_pipe: 0
        * Connected to 10.0.1.8 (10.0.1.8) port 3000 (#0)
        > GET /items HTTP/1.1
        > User-Agent: curl/7.30.0
        > Host: 10.0.1.8:3000
        > Accept: */*
        >
        < HTTP/1.1 200 OK
        < ETag: af0057e2-1c6d-4a47-b81a-a754238b60fd
        < Content-Type: application/json
        < Content-Length: 255
        < Connection: keep-alive
        <
        * Connection #0 to host 10.0.1.8 left intact
        [{"name":"Item1","uid":"F465AAD2-AA39-4C33-A57A-F0543C25C476"},
         {"name":"Item2","uid":"6505A82E-A473-4A7D-BC4B-BCBEFFFE8E9C"}]
        

        我的responseObject 是服务器响应正文中的项目数组,而不是NSURLResponse。以下是我检索标题的方式:

        void (^handleSuccess)(NSURLSessionDataTask *, id) = ^(NSURLSessionDataTask *task, id responseObject) {
            // handle response headers
            NSHTTPURLResponse *response = ((NSHTTPURLResponse *)[task response]);
            NSDictionary *headers = [response allHeaderFields];
        
            // handle response body
            NSArray *responseItems = responseObject;
            for (NSDictionary *item in responseItems) {
                [self.activeDataController createObject:item];
            }
        };
        

        【讨论】:

        • 完美解释为什么接受的答案是错误的。
        【解决方案5】:

        对于 Swift 2.0:

        if let response = operation.response {
            print(response.allHeaderFields)
        }
        

        【讨论】:

        • 虽然这段代码 sn-p 可以解决问题,但代码外的including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-27
        • 1970-01-01
        • 2011-08-25
        • 2017-01-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多