storing values in NSUserDefaults, from JSON serialization, causes unwanted exceptions

I’ve got an app where I use a JSON based API. As part of JSON, often values are set to “null“. This may be common:

{"data":["one","two","three"],"name":null,otherstuff:10}

Recently I’ve tried to store a misc NSDictionary hierarchy, converted from a JSON object, in NSUserDefaults. Unfortunately it causes an exception if there is null data, converted in IOS to [NSNull null]. Apparently that can’t be saved in prefs.

  • How to convert min to hours in swift3?
  • How To Handle json null values in Swift
  • Swift Admob Interstitial Error
  • What describes nil best? What's that really?
  • Sending NSCFCalendar nil NSDate Sarcastic Error
  • NSArray arrayWithObjects: if nil is meant to mark array end, can I do …nil, nil]?
  • I was wondering if anyone has worked around this before? I tried to add some logic to remove all null values from the JSON first, with limited success, but it seems inappropriate to have to modify the data before storing it. Is there a better way to handle this?

    2 Solutions Collect From Internet About “storing values in NSUserDefaults, from JSON serialization, causes unwanted exceptions”

    You can first convert your NSDictionary to NSData, then safely store in NSUserDefaults (since NSNull conforms to NSCoding).

    //archive
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dictionary];
    [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"key"];
    
    //unarchive
    NSData *newData = [[NSUserDefaults standardUserDefaults] objectForKey:@"key"];
    NSDictionary *newDict = [NSKeyedUnarchiver unarchiveObjectWithData:newData];
    

    Edit: Original data object was being referenced instead of newData object.

    I’ve tried some recursive solutions but they tend to be complicated and don’t handle mixed type content well. At the simplest level here is a flat example that works well if you have a predictable, flat response to clean.

    NSMutableDictionary *dictMutable = [dict mutableCopy];
    [dictMutable removeObjectsForKeys:[dict allKeysForObject:[NSNull null]]];