Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSUserDefaults won't save NSDictionary

I'm writing an application which uses NSUserDefaults as the data storage mechanism, and am hitting a problem when trying to save data (that conforms to the Property List protocols):

+ (BOOL)storeAlbum:(Album *)album
{
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *albums = (NSMutableDictionary *)[prefs objectForKey:@"my_adventure_book_albums"];
    NSLog(@"Existing albums: %@",albums);
    if (!albums)
        albums = [NSMutableDictionary dictionaryWithObject:album forKey:@"album"];
    else
        [albums setObject:album forKey:@"album"];
    NSLog(@"%@",album);
    [prefs setObject:albums forKey:@"my_adventure_book_albums"];
    return [prefs synchronize];
}

I get this output:

2010-06-29 17:17:09.929 MyAdventureBook[39892:207] Existing albums: (null)
2010-06-29 17:17:09.930 MyAdventureBook[39892:207] test
2010-06-29 17:17:09.931 MyAdventureBook[39892:207] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '{
    album = test;
}' of class 'NSCFDictionary'.

The description method of Album looks like:

- (NSString *)description
{
    // Convert to a NSDictionary for serializing
    if (!title) title = @"";
    if (!date) date = [NSDate dateWithTimeIntervalSinceNow:0];
    if (!coverImage) coverImage = @"";
    if (!images) images = [[NSArray alloc] initWithObjects:@"",nil];

    //NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:title,date,coverImage,images,nil] forKeys:[NSArray arrayWithObjects:@"title",@"date",@"coverImage",@"images",nil]];
    //NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:title,nil] forKeys:[NSArray arrayWithObjects:@"title",nil]];
    //return [dict description];
    return @"test";
}

All of the commented-out lines have the same result, so I just decided to see if the NSString "test" would work, which it (of course) doesn't.

like image 647
Jason B Avatar asked Jan 20 '26 14:01

Jason B


2 Answers

But the object you put inside the dictionary, an Album* is most likely not a property list object, is it? Every object, all the way down, needs to be a property list object for this to work. A description method isn't good enough to make this happen.

As a workaround, you can use NSCoding and an NSKeyedArchiver to write out your dictionary to an NSData, which you can store among the preferences.

like image 65
Jakob Borg Avatar answered Jan 22 '26 08:01

Jakob Borg


You can only put basic foundation types into a property list. NSUserDefaults writes preferences out as a property list. See here for property list allowed types. In a nutshell, it is numbers, strings, data, dates, and arrays and dictionaries of those. Dictionaries must have string keys.

like image 29
drawnonward Avatar answered Jan 22 '26 08:01

drawnonward



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!