質問

I'm using AFNetworking to process HTTP requests in my iOS app. I have run into a stumbling block. I cannot be certain of what the response content type will be, but you have to set the response serializer BEFORE the request is processed. This means I could do an API request, expecting an image back, but actually there's some authentication error, so the server returns a JSON-formatted response instead.

Here's my code:

AFHTTPRequestOperation* op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[op setResponseSerializer:[AFJSONResponseSerializer serializer]]; // ??????
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
 {
     NSDictionary* result = (NSDictionary*) responseObject;
     onSuccess((NSArray*) result);
 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     onFailure(error);
 }];
[op start];

As you can see, I've had to set the expected content type implicitly by setting the responseSerializer to [AFJSONResponseSerializer serializer]. So if I get something else back, it causes an error, even though I may still wish to parse an process that response when dealing with the error.

So my question is, should I just use the standard AFHTTPResponseSerializer, examine the response status code and then process the response body manually (as json, xml, html an image etc)?

役に立ちましたか?

解決

Set the accepted content types you want on the serialiser with acceptableContentTypes:

AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
serializer.acceptableContentTypes = [NSSet setWithArray:@[@"text/plain", @"text/html"]];
[op setResponseSerializer:serializer];

From the docs:

By default, AFJSONSerializer accepts the following MIME types, which includes the official standard, application/json, as well as other commonly-used types:

application/json
text/json

You don't have to use AFJSONResponseSerializer, as you can create your own serializer as long as it conforms to the AFURLResponseSerialization protocol.

If you have JSON responses but XML error responses, you could just subclass AFHTTPResponseSerializer and do your own processing in there.

You could also use AFCompoundResponseSerializer to parse different response types just going through the serializers you give it.

他のヒント

Your API is a little unusual: if you aren't authorized, it should just use an HTTP 401 response, not JSON. But there's plenty of unusual API's out there and I bet you don't have control over this one.

The fix is straightforward:

Make an implementation of AFURLResponseSerialization that just acts as a proxy, and assign that one as the serializer for your request. When the response comes in, have it take a quick look at the data and then instantiate and call the right serializer.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top