0

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.

SAHM
  • 4,078
  • 7
  • 41
  • 77
  • Can't you simply test if the file is in the library directory and if so, use it from there, and if it's in the documents directory move it across and then start using it? I don't understand the complication. – Droppy Jun 12 '16 at 09:19

1 Answers1

2

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

emotality
  • 12,795
  • 4
  • 39
  • 60
  • `[NSHomeDirectory() stringByAppendingPathComponent:@"Library"];`? I don't think so... – Droppy Jun 12 '16 at 09:20
  • NSHomeDirectory(): `/Application/DAF1FB3A-3ED3-464C-AAEB-CC21F3761355` NSLibraryDirectory: `/Application/DAF1FB3A-3ED3-464C-AAEB-CC21F3761355/Library` NSDocumentsDirectory: `/Application/DAF1FB3A-3ED3-464C-AAEB-CC21F3761355/Documents` – emotality Jun 12 '16 at 09:23
  • You're supposed to use `NSSearchPathForDirectoriesInDomains`. – Droppy Jun 12 '16 at 09:25
  • It's the same.. Why have array, then pick the only object [0] if you can just use the above? – emotality Jun 12 '16 at 09:26
  • Because that's what it tells you do use in the link you provide. – Droppy Jun 12 '16 at 09:27