Search code examples
iosobjective-cwritetofile

Saving files using writeToFile


So I've found a small issue with saving an array using writeToFile to retrieve it later on. I'm using:

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                             NSUserDomainMask, YES);
        if ([paths count] > 0)
        {
            NSString *arrayPath = [[paths objectAtIndex:0]
                         stringByAppendingPathComponent:@"array.out"];

            [finalSavedArray writeToFile:arrayPath atomically:YES];
            [[NSUserDefaults standardUserDefaults] setObject:arrayPath forKey:@"SavedArrayPath"];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }

to save 'finalSavedArray' as a file, and later retrieving this array using:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        NSLog(@"File path: %@",[[NSUserDefaults standardUserDefaults] objectForKey:@"SavedArrayPath"]);
        NSMutableArray *savedArray = [NSMutableArray arrayWithContentsOfFile:[[NSUserDefaults standardUserDefaults] objectForKey:@"SavedArrayPath"]];
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"SAVED ARRAY:%@",savedArray);
        });

    });

This works fine when I access the file soon after saving it, but when I restart the app the array comes out as being null and seemingly not found in the saved directory. From a bit of reading it seems that this file directory should be relative as the one that I'm saving to at the moment changes every time you open the app, but I haven't quite been able to figure out how to change my code in order to save it to a relative directory. Any help would be greatly appreciated :)


Solution

  • An app's path can change. Never, ever store the absolute path of a file. In your case, just store the path relative to the Documents folder.

    When you want to read the file, read the relative path from NSUserDefaults and then rebuild the full path just like you do to write the file.

    Writing the file:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    if ([paths count] > 0)
    {
        NSString *arrayPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"array.out"];
    
        [finalSavedArray writeToFile:arrayPath atomically:YES];
        [[NSUserDefaults standardUserDefaults] setObject:[arrayPath lastPathComponent] forKey:@"SavedArrayPath"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    

    Reading the file:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *filename = [[NSUserDefaults standardUserDefaults] objectForKey:@"SavedArrayPath"];
        NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:filename];
        NSMutableArray *savedArray = [NSMutableArray arrayWithContentsOfFile:path];
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"SAVED ARRAY:%@",savedArray);
        });
    
    });