Download an image with AFHTTPClient

362 views Asked by At

I'm trying do download a jpeg-file from a server with AFNetworking. It seems to succeed accessing the server but the responseObject is empty.

Following is the relevant code:

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:"https://api.test.info/"];
[client registerHTTPOperationClass:[AFJSONRequestOperation class]];
[client setDefaultHeader:@"Accept" value:@"application/json"];
[client setParameterEncoding:AFJSONParameterEncoding];
[client setAuthorizationHeaderWithUsername:@"username" password:@"password"];

[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"image/jpeg"]];
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];

[client getPath:@"image/number1" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject){
    NSData *test = responseObject;
    NSLog(@"%@", responseObject);
    NSLog(@"%@", test);
    [self.imgProfile setImage:[UIImage imageWithData:test]];
}failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"%@", error);
}];

Output of this code is: (null) (null)

That means responseObject and test are empty objects. If I use the same URL in my browser I get the picture back easily. Username and password are valid, because other requests work.

What do I need to change, to download the image?

Any help is appreciated.

2

There are 2 answers

1
Fogmeister On BEST ANSWER

You are telling the client to use a JSON request. JSON is not an image.

If you want NSData then you can do this...

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:"https://api.test.info/"];
[client setAuthorizationHeaderWithUsername:@"username" password:@"password"];

[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];

[client getPath:@"image/number1" parameters:nil success:^(AFHTTPRequestOperation *operation, NSData responseObject){
    [self.imgProfile setImage:[UIImage imageWithData:responseObject]];
}failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"%@", error);
}];

Or, if self.imgProfile is a UIImageView then it's even easier...

[self.imgProfile setImageWithURL:[NSURL URLWithString:@"https://api.test.info/image/number1"]];

Not sure how this works with authorization though.

Actually, this is what to do...

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:"https://api.test.info/"];
[client setAuthorizationHeaderWithUsername:@"username" password:@"password"];

NSURLRequest *request = [client requestWithMethod:@"GET" path:@"image/number1" parameters:nil];

[self.imgProfile setImageWithURLRequest:request placeholderImage:nil success:nil failure:nil];
1
dfinki On

I think Fogmeister's solution should work too, as he handles every request as NSData. Instead of registering the AFHTTPOperationClasses.

My solution:

  1. [self registerHTTPOperationClass:[AFImageRequestOperation class]];

  2. Be sure your URL uses an extension.

This was my situation:

I have a API from which I request data and images, to get access to data and images I need the username and password set in the header. The best (only?) way to do this is by subclassing AFHTTPClient and using it as a singleton throughout my application.

Everything worked fine for the JSON-Data I had to receive, but a few days ago I wanted to request the pictures. Well pictures obviously are not JSON-Data, but nonetheless I tried to request them through my singleton.

The request succeeded, BUT there was no data in my responseObject.

First thing, google and reading, stackoverflow and reading… Not really helpful, because the possibilities I found work all without using authentication.

So what did I do?

I tried registering the class AFImageRequestOperation as HTTPOperationClass for my HTTPClient.

[self registerHTTPOperationClass:[AFImageRequestOperation class]];

That didn't help, because the method

+ (BOOL)canProcessRequest:(NSURLRequest *)urlRequest

of AFImageRequestOperation only checks for the extension of the URL.

And the URL i was calling didn't have any extensions. First I quickly customized AFJSONRequestOperation, so that it could also return images, as NSData. Just to check if everything else works fine.

Now i told my colleague to change the API a little, so that I could call the URL with the suffix "jpg".

Now everything works just fine.

Just wanted to tell this somewhere! In case anybody is running into the same problem.