iosnsfilemanagernsdocumentdirectoryapp-updatenslibrarydirectory

How should iOS app data files for new app version be moved from NSDocumentDirectory to NSLibraryDirectory?


In the current version of my app, I have stored two important app files (my Core Data .sqlite file and my SettingsFile.plist) in the NSDocumentDirectory. In the next version, I want to move these files to the NSLibraryDirectory. Neither needs to be directly accessed by the user for editing, and it seems from my research that this is the best option for each of these files.

I am concerned with how to move the files for all of my current app users from the NSDocumentDirectory to the NSLibraryDirectory. I want to be very careful not to lose any of the users' data. I don't know where or how to begin to go about moving these files in a very safe way. I am hoping someone can point me in the right direction.


Solution

  • You can use NSFileManager to check if the files already exist in Library folder, if not, move them. If move was successful, delete old file and return the new path, if not, return the old path. See below:

    ...
    NSString *mySQLfilePath = [self getFilePathWithName:@"database.sqlite"];
    ...
    
    - (NSString *)getFilePathWithName:(NSString *)filename
    {
        NSString *libPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library"];
        NSString *docPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    
        NSString *fileLibPath = [libPath stringByAppendingPathComponent:filename];
        NSString *fileDocPath = [docPath stringByAppendingPathComponent:filename];
    
        if ([[NSFileManager defaultManager] fileExistsAtPath:fileLibPath]) {
            // file already exists in Library folder
            return fileLibPath;
    
        } else if ([[NSFileManager defaultManager] fileExistsAtPath:fileDocPath]) {
            // file exists in Documents folder, so move it to Library
            NSError *error = nil;
            BOOL moved = [[NSFileManager defaultManager] moveItemAtPath:fileDocPath toPath:fileLibPath error:&error];
            NSLog(@"move error: %@", error);
    
            // if file moved, you can delete old Doc file if you want
            if (moved) [self deleteFileAtPath:fileDocPath];
    
            // if file moved successfully, return the Library file path, else, return the Documents file path
            return moved ? fileLibPath : fileDocPath;
        }
    
        // file doesn't exist
        return nil;
    }
    
    - (void)deleteFileAtPath:(NSString *)filePath
    {
        if ([[NSFileManager defaultManager] isDeletableFileAtPath:filePath]) {
            NSError *error = nil;
            [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
            NSLog(@"delete error: %@", error);
    
        } else {
            NSLog(@"can not delete file: %@", filePath);
        }
    }
    

    If you have questions, feel free. And just for visitors reference:

    https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html