Search code examples
objective-ciosnsdatansfilemanager

ios fileExistsAtPath failing for new file


I am writing a file, then adding the NSURLIsExcludedFromBackupKey attribute to the file. To do this I have the following two methods in my HPSFileHelper class:

+(void)writeDataToFileWithData:(NSData*)data andFilename:(NSString*)fileName
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

    NSString *documentsDirectory = [paths objectAtIndex:0]; 

    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];

    [data writeToFile:filePath atomically:YES];

    NSURL* fileURL = [NSURL fileURLWithPath:filePath];

    [HPSFileHelper addSkipBackupAttributeToItemAtURL:fileURL]; // Prevent this file from being backed up.
}

+(BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);

    NSError *error = nil;
    BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
                                  forKey: NSURLIsExcludedFromBackupKey error: &error];
    if(!success){
        NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
    }
    return success;

}

The problem is that the assert ... fileExistsAtPath is failing occasionally. Presumably this is because sometimes a file has not been fully written and unlocked by the time the assert runs? (for large files?)

How should I code around this issue?


Solution

  • Subsequent investigation reveals that writeToFile is synchronous, and the file WILL have been written by the time the method returns.

    The issue was caused by encountering an auto-generated filename that contained a slash char '/'. This meant the file creation failed. I have now changed the writeToFile;atomically to:

    BOOL bWorked = [data writeToFile:filePath options:NSDataWritingAtomic error:&errorPtr];
    
    if (!bWorked)
    {
        NSLog(@"writeDataToFileWithData failed for %@ %@", filePath,errorPtr);
    }