writeToFile:atomically: not working in 4.1 SDK and below but works on 4.2 beta SDK
I use the following code to write to the plist (assuming dict is already populated):
[dict writeToFile:[appDelegate dataFilePath] atomically:YES];
where in my App Delegate:
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
And I read the plist from disk using this开发者_C百科:
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithContentsOfFile:[appDelegate dataFilePath]];
This worked when compiling my app for 4.2, but since I brought it down to 4.1 for distribution, it stopped working.
[dict writeToFile:[appDelegate dataFilePath] atomically:YES];
returns NO. What's wrong here?
I would guess that some other change is resulting in an object of non-plist type being present in your dictionary. See what happens if you separate out the "generate plist" and "write plist" steps:
/* Generate plist. */
NSError *error = nil;
NSData *data = [NSPropertyListSerialization
dataFromPropertyList:dict
format:NSPropertyListBinaryFormat_v1_0
options:0/*unused*/
error:&error];
if (!data) {
NSLog(@"%s: Failed to serialize data: %@", __func__, error);
return;
}
/* Write data. */
NSString *path = [appDelegate dataFilePath];
BOOL ok = [data writeToFile:dataFilePath options:NSDataWritingAtomic error:&error];
if (!ok) {
NSLog(@"%s: Failed to write atomically to path %@: %@", __func__, path, error);
}
Okay now I realize it has nothing to do with the base SDK. I cleaned all targets and now the problem is manifested everywhere. I tried switching over to using NSUserDefaults instead of writeToFile:atomically:, and the same problem happens. I can't understand what's wrong here!
If it doesn't work with NSUserDefaults you most likely have objects in your dictionary that do not conform to NSCoding. You could use something like this to find out which key is responsible for this. Of course you have to check your values too.
for (id object in [dict allKeys])
if (![object conformsToProtocol:@protocol(NSCoding)])
NSLog(@"not NSCoding: %@ [%@]", object, [object class]);
精彩评论