DD
DD

Reputation:

How to serialize a NSDictionary/NSArray/Property List (plist) which contains NSNull

I want to store in a NSMutableDictionary some null values using NSNull and then serialize this data using a property list. Problem is NSNull is not allowed and I get "Property list is in invalid format" error. Is there a workaround for this? Seems very surprising they didn't put NSNull on the list of valid plist objects.

Upvotes: 12

Views: 7224

Answers (4)

Saurabh Wadhwa
Saurabh Wadhwa

Reputation: 1173

I convert NSArray or NSDictionary to NSData before serializing. Following is a category on nsarray for serializing and deserializing. This comfortableby handles some data being nsnull

@implementation NSArray(Plist)

-(BOOL)writeToPlistFile:(NSString*)filename{
    NSData * data = [NSKeyedArchiver archivedDataWithRootObject:self];
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentsDirectory = [paths objectAtIndex:0];
    NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
    BOOL didWriteSuccessfull = [data writeToFile:path atomically:YES];
    return didWriteSuccessfull;
}

+(NSArray*)readFromPlistFile:(NSString*)filename{
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentsDirectory = [paths objectAtIndex:0];
    NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
    NSData * data = [NSData dataWithContentsOfFile:path];
    return  [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

Upvotes: 14

Jon Hess
Jon Hess

Reputation: 14247

Instead of using a property list, consider using an NSKeyedArchiver and NSKeyedUnarchiver. Properties lists have a fixed set of types, and that doesn't include NSNull, and it isn't meant to be extended.

Here are links to the relevant documentation: NSCoding, NSKeyedArchiver and NSKeyedUnarchiver.

Upvotes: 9

AlBlue
AlBlue

Reputation: 24040

From the documentation of NSPropertyListSerializationClass:

A property list object. plist must be a kind of NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary object. Container objects must also contain only these kinds of objects.

So you need to have one of those. Depending on the type of data, you could put in a placeholder instead of NSNull and then do a process before/after loading the .plist (like, for example, using a zero-length NSData object to represent your NSNull in the plist). Exactly what kind of placeholder would be dependent on what kind of data you are storing, and choosing something to avoid. Then, after loading, translate the empty NSData back to NSNull.

Upvotes: 3

Jens Ayton
Jens Ayton

Reputation: 14558

No, there is no way to put NSNull in a property list. (Trivia: the binary property list format actually supports nulls, but the writer doesn’t implement support.)

For a dictionary, the easiest workaround is to simply filter out the null values, so { foo = "bar"; baz = null; } becomes { foo = "bar"; }.

Upvotes: 6

Related Questions