Oskar
Oskar

Reputation: 329

iOS: read raw plist

I want to read the UserDefaults plist but not as Dictionary or Data. I want it as string like it is when you open it with an editor.

NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *homeDir = [documentsPath stringByReplacingOccurrencesOfString:@"Documents" withString:@""];
NSString *defaultsPath = [homeDir stringByAppendingString:[NSString stringWithFormat:@"Library/Preferences/%@.plist", [[NSBundle mainBundle] bundleIdentifier]]];
NSData *data = [NSData dataWithContentsOfFile:defaultsPath];

Already tried:

`NSString *contents = [NSString stringWithContentsOfFile:defaultsPath encoding:NSUTF8StringEncoding error:&error];

which ends up with

The operation couldn’t be completed. (Cocoa error 261.)

Upvotes: 0

Views: 1225

Answers (1)

dreamlax
dreamlax

Reputation: 95355

Property list formats can be either binary or text. Binary plists can't be loaded into an NSString because strings are for text, not arbitrary binary data. The error you're getting seems to suggest that the file cannot be interpreted as UTF-8, which either means it is encoded using another encoding or is not text at all.

If you are certain that the property list is a text property list, you can use:

NSStringEncoding enc;
NSString *contents = [NSString stringWithContentsOfFile:defaultsPath usedEncoding:&enc error:&error];

This will allow the framework to determine the encoding of the text plist for you. If it isn't a text plist, you can convert it to one using the plutil command line utility:

plutil -convert xml1 file.plist

Or, alternatively you can do this in code by loading the plist using the NSPropertyListSerialization class, obtaining the NSData from it that represents the plist as the XML format, and then convert that to a string.

An example would be [uncompiled and untested]:

// load the file as-is into a data object
NSData *data = [NSData dataWithContentsOfFile:defaultsPath];

// convert the plist data into actual property list structure
id plistFile = [NSPropertyListSerialization propertyListWithData:data
                                                         options:0
                                                          format:NULL
                                                           error:&error];

// get the XML representation of the property list
NSData *asXML = [NSPropertyListSerialization dataWithPropertyList:plistFile
                                                           format:NSPropertyListXMLFormat_v1_0
                                                          options:0
                                                            error:&error];

// convert the NSData object into an NSString object
NSString *asString = [[NSString alloc] initWithData:asXML encoding:NSUTF8StringEncoding];

This should work whether the original plist is in XML or binary format. In this example, I am assuming that the XML representation of the property list is in fact UTF-8 encoded, as this is the most common encoding for XML data.

Upvotes: 3

Related Questions