[__NSArrayM objectForKeyedSubscript:]: unrecognized selector sent to instance - source code and screenshot attached

Alexander Farber picture Alexander Farber · Jan 21, 2014 · Viewed 11.6k times · Source

At GitHub I have a simple iPhone app, which fetches user information (by using OAuth) from the social network Mail.ru:

app screenshot

It does fetch and print the information, but then crashes.

As an iOS programming newbie I'm confused by the output below (also please see the full output at PasteBin):

2014-01-21 21:21:10.873 oauthMailru[8228:3307] -[__NSArrayM objectForKeyedSubscript:]: unrecognized selector sent to instance 0x8a97290
2014-01-21 21:21:10.875 oauthMailru[8228:3307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKeyedSubscript:]: unrecognized selector sent to instance 0x8a97290'
*** First throw call stack:
(
    0   CoreFoundation                      0x01aa65e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x018298b6 objc_exception_throw + 44
    2   CoreFoundation                      0x01b43903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
    3   CoreFoundation                      0x01a9690b ___forwarding___ + 1019
    4   CoreFoundation                      0x01a964ee _CF_forwarding_prep_0 + 14
    5   oauthMailru                         0x00003a62 __47-[ViewController fetchMailruWithToken:ForUser:]_block_invoke + 402
    6   Foundation                          0x01545695 __67+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]_block_invoke_2 + 151
    7   Foundation                          0x014a5945 -[NSBlockOperation main] + 88
    8   Foundation                          0x014fe829 -[__NSOperationInternal _start:] + 671
    9   Foundation                          0x0147b558 -[NSOperation start] + 83
    10  Foundation                          0x01500af4 __NSOQSchedule_f + 62
    11  libdispatch.dylib                   0x021344b0 _dispatch_client_callout + 14
    12  libdispatch.dylib                   0x02121018 _dispatch_async_redirect_invoke + 202
    13  libdispatch.dylib                   0x021344b0 _dispatch_client_callout + 14
    14  libdispatch.dylib                   0x02122eeb _dispatch_root_queue_drain + 287
    15  libdispatch.dylib                   0x02123137 _dispatch_worker_thread2 + 39
    16  libsystem_pthread.dylib             0x024c0dab _pthread_wqthread + 336
    17  libsystem_pthread.dylib             0x024c4cce start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Does anybody please know what's happening and how to read such crashes?

My source files: ViewController.m, which displays UIWebView and then segues to DetailViewController.m

Answer

rob mayoff picture rob mayoff · Jan 21, 2014

Your code thinks the JSON deserializes to an object (dictionary), but in fact it deserializes to an array containing one object. Try this:

 NSMutableArray *topLevelArray = [NSJSONSerialization JSONObjectWithData:data
     options:NSJSONReadingMutableContainers error:nil];
 NSDictionary *dict = topLevelArray[0];

If you want to check what you're getting, you can use isKindOfClass: like this:

id jso = [NSJSONSerialization JSONObjectWithData:data
    options:NSJSONReadingMutableContainers error:nil];
if (jso == nil) {
    // Error.  You should probably have passed an NSError ** as the error
    // argument so you could log it.
} else if ([jso isKindOfClass:[NSArray class]]) {
    NSArray *array = jso;
    // process array elements
} else if ([jso isKindOfClass:[NSDictionary class]]) {
    NSDictionary *dict = jso;
    // process dictionary elements
} else {
    // Shouldn't happen unless you use the NSJSONReadingAllowFragments flag.
}