Re: NSUserDefaults Croaks on Dictionary Containing NSNumber as Key
Re: NSUserDefaults Croaks on Dictionary Containing NSNumber as Key
- Subject: Re: NSUserDefaults Croaks on Dictionary Containing NSNumber as Key
- From: Chris Parker <email@hidden>
- Date: Sat, 12 Dec 2009 10:20:24 -0800
As Clark noted elsewhere, you're using a string key properly with NSUserDefaults itself and NSUserDefaults and CFPreferences both require that the entire subtree of the value be a properly formed property list object.
For NSDictionaries that means all keys must be strings for the entire tree. The documentation makes a small statement here:
http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/PropertyLists/AboutPropertyLists/AboutPropertyLists.html#//apple_ref/doc/uid/10000048i-CH3-54303
by saying this:
And although NSDictionary and CFDictionary objects allow their keys to be objects of any type, if the keys are not string objects, the collections are not property-list objects.
You can see this in action with this code:
NSError *error = nil;
NSDictionary *dict = [NSDictionary dictionaryWithObject:@"bob" forKey:[NSNumber numberWithInt:34]];
NSData *dataFromDict = [NSPropertyListSerialization dataWithPropertyList:dict format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
if (!dataFromDict) {
NSLog(@"Error: %@", error);
}
Jerry, could you file a bug that perhaps that statement needs to be called out better somehow? Another bug for the error not being useful would be great. You're not the first person to trip over this. Thanks!
.chris
On 11 Dec 2009, at 11:10 PM, Jerry Krinock wrote:
> Sorry for the wonky subject. It's easier to explain in code:
>
> NSNumber* innerKey = [NSNumber numberWithInt:0] ;
> NSDictionary* dic = [NSDictionary dictionaryWithObject:@"Hello"
> forKey:innerKey] ;
> [[NSUserDefaults standardUserDefaults] setObject:dic
> forKey:@"outerKey"] ;
>
> Result:
>
> *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '{
> 0 = Hello;
> }' of class 'NSCFDictionary'.
>
> If I change innerKey to a string such as @"0", then all works fine.
>
> In my opinion, after reading the documentation carefully, this exception is a false alarm. First of all, NSCFDictionary *is*, as required, one of the "property list" objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. Furthermore, all of its objects and keys are themselves property list objects. Furthermore, NSNumber conforms to NSCopying protocol, as required for dictionary keys.
>
> Is there some other requirement that I missed?
>
> Jerry Krinock
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden