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

4 Solutions Collect From Internet About “How to serialize a NSDictionary/NSArray/Property List (plist) which contains NSNull”

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];
}

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.

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”; }.

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.