0

I have a JSON that is a structured as an array of dictionaries.

The normal structure would be something like, (after parsing into array):

[0] - [NSDictionary *] 3 key/value pairs
   [0] departure - 1 element
      -> key @"city"
      -> value @"New York"
   [1] arrival -1 element
      -> key @"city"
      -> value @"Atlanta" 
   [2] bus -3 key/values pairs
      -> key @"bus"
      -> value (NSDictionary *) 3 key/value pairs 
            [0] @"number" (long) 123 
            [1] @"driver" @"smith"
            [2] @"type" @"40 seat coach"

However, if you parse a "bad" JSON that has the structure but one of the key elements is missing (ie last element)

[0] - [NSDictionary *] 3 key/value pairs
   [0] departure - 1 element
      -> key @"city"
      -> value @"New York"
   [1] arrival -1 element
      -> key @"city"
      -> value @"Atlanta" 
   [2] bus -3 key/values pairs
      -> key @"bus"
      -> value (NSNull *)  0x8976656
            -> NSObject

If I try to query the driver's name under bus it crashes. I've tried to test for the null but doesn't work. It doesn't throw an error during the request either (NSURLSessionDataTask). How do you guard against this?

NSArray *busCompany = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];

myBuses =[[NSMutableDictionary]alloc]init];

for (NSDictionary *companiesDict in busCompany) {
   myBuses = companiesDict[@"bus"];
   if(myBuses) {        //also tried if(myBuses != NULL)
       NSString *driverName = [myBuses ForKey: @"driver"];
    }
}

It gives me [NSNULL objectforkey] error.

koen
  • 5,383
  • 7
  • 50
  • 89
James D
  • 1
  • 2
  • You have not parsed anything, you have just decoded the JSON. Parse dictionaries into class instances and check the format during parsing. When something is missing, reject the whole data. – Sulthan Oct 13 '20 at 18:47
  • Also, you have to check for NSNull instances. – Sulthan Oct 13 '20 at 18:48
  • *Also* try ```myBuses != NSNull.null``` but I am sure it will work infinitely better if you rename that to ```myBusses``` – skaak Oct 13 '20 at 19:23
  • Added relevant code above, its unfortunately not formatting with the CTRL-K or ``` or code button – James D Oct 13 '20 at 19:23
  • Can you post the outcome of `NSLog(myBuses)` in your question? – koen Oct 13 '20 at 19:32
  • @skaak This worked, but it does warn that "Comparison of distinct pointer types NSDictionary and NSNull" – James D Oct 13 '20 at 19:50
  • @koen Just prints – James D Oct 13 '20 at 19:54
  • What would you do if one of the keys was missing (i.e "driver") but the other ones were there? – James D Oct 13 '20 at 19:58
  • Do the same check as above for each key-value pair. – koen Oct 13 '20 at 20:03
  • I tried that. Checking for a key name that doesn't exist ([myBuses objectAtKey:@"driver"] != NSNull.null) within the NSDictionary crashes the app. – James D Oct 13 '20 at 20:11
  • 1
    https://stackoverflow.com/questions/37459560/ios-detecting-nsnull-from-json-not-working That's how you check `NSNull` in Objective-C. You might want to parse with custom NSObject, and there, you have have a "nullable init", for "invalid" responses. – Larme Oct 13 '20 at 20:44
  • Per the post 37459560 above, The JSON response is not null nor nil. It returns an array but the array structure changes, element to element. Again, the "bus" element should have a "driver" element. Sometimes it does and sometimes it does not. If I try to query an element that does not exist, that is when the exception error occurs. – James D Oct 14 '20 at 16:56
  • @JamesD Hi - your reply to me, that it works, but you get a warning. Of course you'll get that warning, because either you have a dictionary or a JSON null. You can get away from it by assigning it to an NSObject and then, after checking, casting to NSDictionary, but the warning is not a train smash and easy to understand and live with. – skaak Oct 19 '20 at 04:23

0 Answers0