Search code examples
iosafnetworking

-[__NSDictionaryI arrayForKey:]: unrecognized selector sent to instance


I got this error when using the AFNetworking 3.0 library. Code:

[manager GET:@"..."
      parameters:nil
        progress:nil
         success:^(NSURLSessionTask *task, id responseObject) {
             NSArray *result = [responseObject arrayForKey:@"items"];

             self.objects = [NSMutableArray arrayWithArray:responseObject];
             [self.tableView reloadData];
         } failure:^(NSURLSessionTask *operation, NSError *error) { NSLog(@"Error: %@", error); }];

When I use arrayWithArray, I get:

[NSArray initWithArray:range:copyItems:]: array argument is not an NSArray'

Solution

    1. You should never trust user input, data that comes from network and other 3rd-party data with dubious origin, so you should always check if you are getting what you expect. Even if you assume that responseObject is a NSDictionary, you must check it in order to be sure and correctly handle possible errors.

    2. In your example (according to the crash message) responseObject is of NSDictionary type. This class does not have -[arrayForKey:] method. When you are trying to call a method (to send a message, actually) that is not implemented in the hierarchy, you get that type of exception – "unrecognized selector sent to instance". Also, check this article regarding forwarding for extended info.

    Fixed snippet:

    [manager GET:@"..."
     parameters:nil
      progress:nil
       success:^(NSURLSessionTask *task, id responseObject) {
        if ([responseObject isKindOfClass:[NSDictionary class]]){
            NSDictionary *dic = (NSDictionary*)responseObject;
            id items = dic[@"items"];
            if ([items isKindOfClass:[NSArray class]]){
                self.objects = [(NSArray*)items mutableCopy];
                [self.tableView reloadData];
            } else {
                NSLog(@"Error: \"items\" is not an array");
            }
        } else {
            NSLog(@"Error: unexpected type of the response object");
        }
    } failure:^(NSURLSessionTask *operation, NSError *error) {             
        NSLog(@"Error: %@", error);
    }];