0

I am allowing for application data (it's a Mac app on 10.7) to be exported as an XML file, and one field I would like to be able to export/import to/from XML is an NSData field. What would be the correct/accepted way of doing this? Should I convert to base64 and write that string to XML?

I would prefer not to roll my own solution, using a category, as the accepted answer to the linked question does (linking to Matt Gallagher's solution).

Update

I just discovered the NSPropertyListSerialization class. I got my hopes up, but it only has static serialization methods which return NSData representations.

Community
  • 1
  • 1
Dov
  • 15,530
  • 13
  • 76
  • 177
  • 1
    I would avoid adding raw data in XML (NSData). If it is possible, I would write another file with the raw data and add its URL to the XML field. If this is not an option, I would convert to string being careful to avoid characters like '>' , '<' that would mess up the structure of the XML – Mircea Apr 16 '12 at 15:27
  • @Mircea I see your point, but the XML format makes sense in this instance. The binary field is only one field of many for the represented entity, and there may be hundreds or more of the entities in the file. I prefer the simplicity and user-editable nature of a single file over creating some sort of bundle. – Dov Apr 16 '12 at 15:36
  • Do you need XML in a specific format, or will the standard Mac OS X property list format do? It's pure XML. – Rob Keniger Apr 17 '12 at 06:18
  • @RobKeniger I'm looking into it now. I'm not sure I'm comfortable with how the plist XML gets embedded as a node in the greater XML doc – it's only partially escaped. `<` becomes `<` but `>` and `"` remain as-is – Dov Apr 17 '12 at 14:37

1 Answers1

0

I realized (as my updated alluded to) that I could use the NSPropertyListSerialization class, since the NSData returned by -dataWithPropertyList:format:options:error: is just a UTF-8 string. This is what I'm using to serialize:

NSData *data = value;

NSError *error = nil;
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:data
                                                               format:NSPropertyListXMLFormat_v1_0
                                                              options:0
                                                                error:&error];
if (error) {
    NSLog(@"Error serializing data to plist XML: %@", error);
} else {
    NSString *plistString = [[NSString alloc] initWithData:plistData encoding:NSUTF8StringEncoding];
    NSXMLElement *dataElement = [NSXMLElement elementWithName:field
                                                  stringValue:plistString];
}

And deserialize:

NSData *plistData = [element.stringValue dataUsingEncoding:NSUTF8StringEncoding];
NSData *originalData = [NSPropertyListSerialization propertyListWithData:plistData
                                                                 options:NSPropertyListImmutable
                                                                  format:NULL
                                                                   error:&error];

if (error) {
    NSLog(@"Error deserializing data from plist XML: %@", error);
} else {
    value = originalData;
}
Dov
  • 15,530
  • 13
  • 76
  • 177