AFNetworking 2.0 // How to read response header
Asked Answered
O

5

12

I'm using the new version of AFNetworking and I can't figure out how to read the headers of the response. I'm using the AFHTTPSessionManager to perform my query, everything works well but I'm unable to find the header response field.

Here is how I proceed

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];
        }
    }
];

I tried to read the response attribute of task but it return an NSURLResponse which doesn't include the headers.

Does anyone now how to read the response headers with the 2.0 version?

Olimpia answered 6/12, 2013 at 10:0 Comment(0)
D
13

Have you tried to get headers from NSURLResponse which is return,

You can try something like with NSURLResponse object,

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

Hope This will Help You.!

Demography answered 6/12, 2013 at 10:29 Comment(8)
I already tried but it seems that the NSURLResponse doesn't include the allHeaderFields method. Only the NSHTTPURLResponse class include itOlimpia
@MtotheK: check the updated answer, convert your responce to NSHTTPURLResponse.Demography
@Virussmca: please don't call casting converting. that is misleading.Uniseptate
I tried this exact same thing and it's working, so your answer is correct thank's for your help !Olimpia
your cast and your selector check are actually in the wrong order: if it responds to allHeaderFields, you know you can safely cast to a class that has this methodUniseptate
@vikingosegundo:I've seen a lot of code, including Apple's SimpleURLConnections sample, that simply cast any NSURLResponse to a NSHTTPURLResponse.Demography
if you know, it is a NSHTTPURLResponse for sure, that is ok. but in your order it makes no sense, as any NSHTTPURLResponse does response to allHeaderFields.Uniseptate
@vikingosegundo's response is correct. This answer didn't work for me, but it wasn't clear enough for me to understand what was going on anyway.Sproul
U
16

a slightly more robust code than Viruss mcs's:

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

returns

{
    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";
}

similarly you can assure the casting is done right with [response respondsToSelector:@selector(allHeaderFields)], but you should also call that before you do the cast

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

or no cast at all:

if ([task.response respondsToSelector:@selector(allHeaderFields)]) {
    NSLog(@"%@" ,[task.response performSelector:@selector(allHeaderFields)]);
}
Uniseptate answered 6/12, 2013 at 10:42 Comment(0)
D
13

Have you tried to get headers from NSURLResponse which is return,

You can try something like with NSURLResponse object,

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

Hope This will Help You.!

Demography answered 6/12, 2013 at 10:29 Comment(8)
I already tried but it seems that the NSURLResponse doesn't include the allHeaderFields method. Only the NSHTTPURLResponse class include itOlimpia
@MtotheK: check the updated answer, convert your responce to NSHTTPURLResponse.Demography
@Virussmca: please don't call casting converting. that is misleading.Uniseptate
I tried this exact same thing and it's working, so your answer is correct thank's for your help !Olimpia
your cast and your selector check are actually in the wrong order: if it responds to allHeaderFields, you know you can safely cast to a class that has this methodUniseptate
@vikingosegundo:I've seen a lot of code, including Apple's SimpleURLConnections sample, that simply cast any NSURLResponse to a NSHTTPURLResponse.Demography
if you know, it is a NSHTTPURLResponse for sure, that is ok. but in your order it makes no sense, as any NSHTTPURLResponse does response to allHeaderFields.Uniseptate
@vikingosegundo's response is correct. This answer didn't work for me, but it wasn't clear enough for me to understand what was going on anyway.Sproul
C
4

It's interesting that the above responses indicate that the parameter id responseObject returns an NSURLResponse. I'm running a JAX-RS server on the backend and I get a different response. When executing a curl command against my server, my response is this:

$ 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"}]

My responseObject is an array of the items in the body of the server response and not an NSURLResponse. Here's how I retrieved the headers:

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];
    }
};
Conveyance answered 17/2, 2014 at 17:44 Comment(1)
Perfect explanation of why the accepted answer is wrong.Sproul
C
3

I subclassed AFHTTPRequestOperationManager and use the:

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

method for most of my web-service requests. When using that method, the response headers will be part of the operation object. Something like this:

[self POST:url parameters:newParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
    // Response headers will be a dictionary
    NSDictionary *headers = operation.response.allHeaderFields;
...
Circinus answered 6/12, 2013 at 10:38 Comment(0)
S
0

For swift 2.0:

if let response = operation.response {
    print(response.allHeaderFields)
}
Sporadic answered 11/11, 2015 at 10:27 Comment(1)
While this code snippet may solve the question, including an explanation out of the code really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations!Dehiscent

© 2022 - 2024 — McMap. All rights reserved.