AFNetworking responseObject alternates between NSArray and NSDictionary in AFHTTPRequestOperation

StackOverflow https://stackoverflow.com/questions/23572424

  •  19-07-2023
  •  | 
  •  

質問

I have a problem using AFNetworking in AFHTTPRequestOperation. The responseObject alternates between NSArray and NSDictionary. Here is how I do a GET request:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:requestURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
      NSLog(responseObject[@"NotAvailableKey"];
    }    
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

The problem is when I'm trying to access a field which is not set in the NSArray object I get the following error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI length]: unrecognized selector sent to instance 0xc1afaa0'

If the responseObject is of the type NSDictionary it works perfectly. Here is my JSON which I get:

(
        {
        "food_id" = 15;
        "food_name" = "fish";
        "user_admin_id" = 3;
        ingredients =         (
                        {
                "ingredients_id" = 3;
                "ingredients_name" = "salt";
            }
        );
    }
)
役に立ちましたか?

解決 2

AFNetworking is just a pipe between your app and the server, you give the impression you think its results should always be the same.

Using isKindOfClass is not the solution either. Your code should know what the expected format and content is when baseurl.com/methodOne is called and how that differs when baseurl.com/methodTwo is called and how that differs when baseurl.com/methodN is called.

If you are calling baseurl.com/methodA you should know that the server is returning the data as an array and what it contains, if you are calling baseurl.com/methodB you should know now its a dictionary and what that contains. Doing it otherwise is the wrong way round.

他のヒント

You can check if the responseObject is an NSDictionary or an NSArray before using it.

if ([responseObject isKindOfClass:[NSDictionary class]]) {
    NSLog([responseObject valueForKey:@"error"]);
}else if ([responseObject isKindOfClass:[NSArray class]]){
    //This is an NSArray, you cannot call 'valueForKey' on this responseObject
}

UPDATE

As pointed out by @Sausages in the comments, this should be used as a recovery for bad server response. You shouldn't handle multiple object types coming from a single server call has a normal behaviour or use the same methods to handle multiple server calls return an do the response handling according to its type.

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