1

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?

simsula
  • 147
  • 7

2 Answers2

4

From the comments in NSDictionary.h:

These methods are deprecated, and will be marked with API_DEPRECATED in a subsequent release. Use the variants that use errors instead.

The variants that use errors are

- (nullable NSDictionary<NSString *, ObjectType> *)initWithContentsOfURL:(NSURL *)url error:(NSError **)error;
+ (nullable NSDictionary<NSString *, ObjectType> *)dictionaryWithContentsOfURL:(NSURL *)url error:(NSError **)error;

and

- (BOOL)writeToURL:(NSURL *)url error:(NSError **)error;

Serializes this instance to the specified URL in the NSPropertyList format (using NSPropertyListXMLFormat_v1_0). For other formats use NSPropertyListSerialization directly.

Willeke
  • 14,578
  • 4
  • 19
  • 47
3

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)
Tim
  • 59,527
  • 19
  • 156
  • 165
  • Another pro of this solution is that it's using methods available since OSX 10.6. +1 – gog Sep 03 '19 at 09:43