Search code examples
databasesqliteosx-yosemitensfilemanager

How to put DB file from application's bundle in the Library/Application support/ directory?


I'm developing a OS X app with sqlite3 and I want to copy the database from the application's bundle to Library/Application support/ directory because I need read/write on the db, however, the sql is copied to my documents folder and I don't want that location. My code:

- (NSString *)filePath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [[paths objectAtIndex:0] stringByAppendingPathComponent:@"myDB.sql"];
}

- (void)openDB {
    NSString *destinationPath = [self filePath];
    if (![[NSFileManager defaultManager] fileExistsAtPath:destinationPath]) {
    NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"myDB.sql"];
    NSError *error;
    [[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:destinationPath error:&error];
    if (error != nil) {
        //Error
    }
}

Solution

  • A file like this belongs in the Application Support folder of the Library. So, instead of NSDocumentDirectory, use NSApplicationSupportDirectory. Also, as the File System Basics documentation says, "All content in this directory should be placed in a custom subdirectory whose name is that of your app’s bundle identifier or your company."

    For example:

    - (NSString *)filePath {
        NSString *applicationSupport = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0];
        NSString *applicationFolder = [applicationSupport stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]];
        return [applicationFolder stringByAppendingPathComponent:@"myDB.sql"];
    }
    

    By the way, when creating this file, remember to create the folder:

    - (void)openDB {
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *destinationPath = [self filePath];
    
        if (![fileManager fileExistsAtPath:destinationPath]) {
            NSError *error;
            if (![fileManager createDirectoryAtPath:[destinationPath stringByDeletingLastPathComponent] withIntermediateDirectories:TRUE attributes:nil error:&error]) {
                NSLog(@"%s: createDirectoryAtPath error: %@", __FUNCTION__, error);
            }
    
            NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"myDB" ofType:@"sql"];
            if (![fileManager copyItemAtPath:sourcePath toPath:destinationPath error:&error]) {
                NSLog(@"%s: copyItemAtPath error: %@", __FUNCTION__, error);
            }
        }
    }