Converting an NSDictionary to a string and back

Posted by: Marc

On occasion, I’ll want to get a string representation of an NSDictionary, and then later take that string and put it back into an NSString. This is best done via the NSPropertyListSerialization class, as NSDictionaries are already property lists.

So, I wrote a simple category extension to do this work for me:

@interface NSDictionary (MLExtensions)

- (NSString *)stringWithXMLPersistenceData;
+ (NSDictionary *)dictionaryFromXMLPersistenceString: (NSString *)xmlPersisted;

@end

And then the implementation is as follows. I added some extra logic to make sure it works on Snow Leopard as well as older versions without warnings.

@implementation NSDictionary (MLExtensions)

- (NSString *)stringWithXMLPersistenceData
{
    NSData *data = [NSPropertyListSerialization dataFromPropertyList: self
                                                format: NSPropertyListXMLFormat_v1_0
                                                errorDescription: NULL];

    char *buf = (char *)malloc([data length] + 1);
    [data getBytes: buf length: [data length]];
    buf[[data length]] = 0;
    NSString *retval = [NSString stringWithUTF8String: buf];
    free(buf);
    return retval;
}

+ (NSDictionary *)dictionaryFromXMLPersistenceString: (NSString *)xmlPersisted
{
    NSPropertyListFormat pf = 0;
    NSData *data = [xmlPersisted dataUsingEncoding: NSUTF8StringEncoding];

#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    id pl = [NSPropertyListSerialization propertyListFromData: data
                                         mutabilityOption: 0
                                         format: &pf
                                         errorDescription: NULL];
#else
    id pl = [NSPropertyListSerialization propertyListWithData: data
                                         options: 0
                                         format: &pf
                                         error: (NSError **)NULL];
#endif // __MAC_OS_X_VERSION_MIN_REQUIRED

    if (pl == nil || ![pl isKindOfClass: [NSDictionary class]])
        return nil;

    return pl;
}

@end

Usage is simple:

NSString *str = [myDict stringWithXMLPersistenceData];
NSDictionary *d = [NSDictionary dictionaryFromXMLPersistenceString: str];

4 Responses So Far... Leave a Reply:

  1. underdogjr says:

    If I use your code in one of the components I’m developing what do I need to do?

  2. Marc says:

    Put the @interface stuff in a file called NSDictionary+MLExtensions.h, and put the @implementation stuff in a file called NSDictionary+MLExtensions.m … save and add these to your project.

    Then, whenever you want to save a dictionary to text, you just include the header file in your .m file, and then can call the methods as if they were on NSDictionary itself.

    NSDictionary *d = [NSDictionary dictionaryWithObject: @"fish" forKey: @"animal"];

    NSString *saveMe = [d stringWithXMLPersistenceData];

    and that’s it!

  3. underdogjr says:

    Cool thanks. I really need this.

  4. underdogjr says:

    Its perfect… To whom do I give credit?
    I want to place it in my code.