Search code examples
iosobjective-cnsdictionarynsuserdefaults

iOS - Attempt to insert non-property list object NSDictionary in NSUserDefaults


In my app, I need to save my custom User object NSDictionary in my NSUserDefaults. I attempt this with the following code:

NSDictionary *userObjectDictionary = response[@"user"];
NSLog(@"USER OBJECT:\n%@", userObjectDictionary);
[defaults setObject:userObjectDictionary forKey:@"defaultUserObjectDictionary"];
[defaults synchronize];

This attempt crashes my app with the following message:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object {type = immutable dict, count = 10, entries => 0 : status_id = 1 : {contents = "first_name"} = exampleFirstName 3 : id = {value = +2, type = kCFNumberSInt64Type} 4 : {contents = "profile_picture"} = {contents = "http://myDevServer.com/pictures/userName.jpg"} 5 : last_name = exampleLastName 7 : email = {contents = "myEmail@gmail.com"} 8 : {contents = "badge_count"} = {value = +0, type = kCFNumberSInt64Type} 9 : user_name = userName 10 : {contents = "phone_number"} = {contents = "0123456789"} 12 : {contents = "status_updated_at"} = } for key defaultUserObjectDictionary'

This is what my User object dictionary looks like before I attempt to save it:

{
    "badge_count" = 0;
    email = "myEmail@gmail.com";
    "first_name" = exampleFirstName;
    id = 2;
    "last_name" = exampleLastName;
    "phone_number" = 0123456789;
    "profile_picture" = "http://myDevServer.com/pictures/userName.jpg";
    "status_id" = "<null>";
    "status_updated_at" = "<null>";
    "user_name" = userName;
}

Is it crashing because there a null values in my User object NSDictionary? I tried with a regular NSDictionary with dummy data with null values and it worked. If this is the problem, how to I bypass this? Sometimes my User object will have properties that are nullable.


Solution

  • Some of your objects or keys in dictionary have class, that doesn't support property list serialization. Please, see this answer for details: Property list supported ObjC types

    I recommend to check object for key "profile_picture" - it may be NSURL.

    If that doesn't help, you may use following code to identify incompatible object:

    for (id key in userObjectDictionary) {
        NSLog(@"key: %@, keyClass: %@, value: %@, valueClass: %@",
              key, NSStringFromClass([key class]),
              userObjectDictionary[key], NSStringFromClass([userObjectDictionary[key] class]));
    }