Search code examples
objective-cnsarraynsdictionarydeprecated

What is the proper way of reading/writing NSDictionary and NSArray to a file in Objective-C in 2018?


The following NSDictionary methods and their equivalent NSArray methods for interacting with files are deprecated:

[NSDictionary dictionaryWithContentsOfURL:]

[NSDictionary dictionaryWithContentsOfFile:]

[NSDictionary initWithContentsOfFile:]

also

[NSDictionary writeToFile:atomically:]

[NSDictionary writeToURL:atomically:]


What am I supposed to use for storing a dictionary/array in Objective C instead?


Solution

  • It's not quite as concise, but you can use the class methods on NSPropertyListSerialization to convert between plist objects (including NSArray and NSDictionary) and NSData, then use API on NSData to read and write from files.

    For example, reading in from a file might look like:

    NSData *fileData = [NSData dataWithContentsOfFile:@"foo"];
    NSError *error = nil;
    NSDictionary *dict = [NSPropertyListSerialization propertyListWithData:fileData options:NSPropertyListImmutable format:NULL error:&error];
    NSAssert([dict isKindOfClass:[NSDictionary class]], @"Should have read a dictionary object");
    NSAssert(error == nil, @"Should not have encountered an error");
    

    Likewise, writing out to a file is similar, but with the two steps reversed:

    NSError *error;
    NSData *data = [NSPropertyListSerialization dataWithPropertyList:dict format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
    NSAssert(error == nil, @"Should not have encountered an error");
    [data writeToFile:@"foo" atomically:YES];
    

    While this takes a few more keystrokes to write, it's…

    • More expressive of the process that is actually occurring (conversion, then file I/O)
    • Clearer about the what actually ends up in the file foo (property list data in XML v1.0 format)
    • More helpful when debugging (out error pointers give failure reasons; NSData has them for I/O as well on other more verbose methods)