AOY
AOY

Reputation: 355

Adding sqlite database: No such file or directory

I wan't to add a sqlite file to preload data for my app. I created this file and copied it into the project directory. I added it to Copy Bundle Resources and copy files. But when I wan't to use this file I get an error saying that there is no such file. I would appreciate if anyone could help me. The code is listed below:

NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"CookBookData" ofType:@"sqlite"]] ;

if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&error]) {
    NSLog(@"Couldn't preload data, error: %@", error);
}

The error:

2015-07-29 15:42:34.342 CookBook v1[2897:24912] Couldn't preload data, error: Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn’t be completed. (Cocoa error 4.)" UserInfo=0x7fe4a35275d0 {NSSourceFilePathErrorKey=/Users/user/Library/Developer/CoreSimulator/Devices/.../data/Containers/Bundle/Application/.../CookBook v1.app/CookBookData.sqlite, NSUserStringVariant=( Copy ), NSDestinationFilePath=/Users/user/Library/Developer/CoreSimulator/Devices/.../Documents/CookBookModel 2.sqlite, NSFilePath=/Users/user/Library/Developer/CoreSimulator/Devices/.../data/Containers/Bundle/Application/.../CookBook v1.app/CookBookData.sqlite, NSUnderlyingError=0x7fe4a35145d0 "The operation couldn’t be completed. No such file or directory"}

I tried to change my code:

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CookBookModel3.sqlite"];
NSError *error = nil;

NSString *storePath = [storeURL path];
NSLog(@"Error %@", error);

NSString *dbName = @"CookBookData.sqlite";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentDirectory stringByAppendingString:dbName];

BOOL success = [fileManager fileExistsAtPath:dbPath];
if (!success) {
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbName];
    success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
    if (success) {
        NSLog(@"Success");
    }
    else{
        NSLog(@"Error %@", [error localizedDescription]);
    }
}
else {
    NSLog(@"Already exists");
}

if (![[NSFileManager defaultManager] copyItemAtPath:dbPath toPath:storePath error:&error]) {
    NSLog(@"Couldn't preload data, error: %@", error);
}

But I get another error:

2015-07-30 12:12:29.118 CookBook[29209:208802] Couldn't preload data, error: Error Domain=NSCocoaErrorDomain Code=516 "The operation couldn’t be completed. (Cocoa error 516.)" UserInfo=0x7fe9526318b0 {NSSourceFilePathErrorKey=/Users/user/Library/Developer/CoreSimulator/Devices/DA5D105A-C9AF-4C91-80B3-DFF2C157CC92/data/Containers/Data/Application/BEED2AB9-BFDA-40AC-A8D0-55DD81F9D985/Library/DocumentationCookBookData.sqlite, NSUserStringVariant=( Copy ), NSDestinationFilePath=/Users/user/Library/Developer/CoreSimulator/Devices/DA5D105A-C9AF-4C91-80B3-DFF2C157CC92/data/Containers/Data/Application/BEED2AB9-BFDA-40AC-A8D0-55DD81F9D985/Documents/CookBookModel3.sqlite, NSFilePath=/Users/user/Library/Developer/CoreSimulator/Devices/DA5D105A-C9AF-4C91-80B3-DFF2C157CC92/data/Containers/Data/Application/BEED2AB9-BFDA-40AC-A8D0-55DD81F9D985/Library/DocumentationCookBookData.sqlite, NSUnderlyingError=0x7fe952610c30 "The operation couldn’t be completed. File exists"} 2015-07-30 12:12:29.121 CookBook[29209:208802] Managed object context

And another variant:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *path = [documentsDir stringByAppendingPathComponent:@"CookBookData.sqlite"]; 
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager copyItemAtPath:path toPath:storePath error:&error];

Upvotes: 0

Views: 925

Answers (2)

Bhanupriya
Bhanupriya

Reputation: 1202

I hope, this gonna help:

NSError *error;
NSString *dbName = @"CookBookData.sqlite";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentDirectory stringByAppendingString:dbName];
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbName];

if ([fileManager fileExistsAtPath:defaultDBPath]) { //check if file exists in NSBundle

    BOOL success = [fileManager fileExistsAtPath:dbPath]; // check if exists in document directory
    if (!success) {

        success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error]; //copy to document directory
        if (success) {
            NSLog(@"Database successfully copied to document directory");
        }
        else{
            NSLog(@"Error %@", [error localizedDescription]);
        }
    }
    else {
        NSLog(@"Already exists in document directory");
    }

}
else{
    NSLog(@"Does not exists in NSBundle");
}

Two things you can check for, go to your document directory of application, check if you can go there and other thing is make sure your sqlite file is properly added to project, you can delete and add again. Let me know, if still there is issue

Upvotes: 1

JordanMazurke
JordanMazurke

Reputation: 1123

Use the following to get the paths to the file in question:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *path = [documentsDir stringByAppendingPathComponent:@"CookBookData.sqlite"];

You can then copy the file with the following:

NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"database.sqlite"];
[fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];

I would include more checking and validation than the above - in particular the fileExistsAtPath: method in NSFileManager.

Upvotes: 2

Related Questions