简体   繁体   中英

Error trying to copy from bundle to documents directory

I have added an sqlite file into my application and is trying to copy it from the bundle to the documents directory. I have added the sqlite to target app as well. Following is the code I use to copy the file:

NSString *destination = [[[Utils applicationDocumentsDirectory] absoluteString] stringByAppendingString:@"myapp.sqlite"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:destination]) {
        NSString *source = [[NSBundle mainBundle] pathForResource:@"myapp" ofType:@"sqlite"];
        NSError *error = nil;
        [fileManager copyItemAtPath:source toPath:destination error:&error];
        if (error) {
            //
        }
    }

Code for [Utils applicationDocumentsDirectory] :

+ (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

But when this code is executed, I get the following error :

Error Domain=NSCocoaErrorDomain Code=4 "The file “myapp.sqlite” doesn't exist." UserInfo={NSSourceFilePathErrorKey=/Users/harikrishnant/Library/Developer/CoreSimulator/Devices/8E531314-F1AE-417F-8E99-7AA92967CDC9/data/Containers/Bundle/Application/0A710929-475D-457C-8D2D-C2F2BBEB6B92/myapp.app/myapp.sqlite, NSUserStringVariant=( Copy ), NSDestinationFilePath=file:///Users/harikrishnant/Library/Developer/CoreSimulator/Devices/8E531314-F1AE-417F-8E99-7AA92967CDC9/data/Containers/Data/Application/13B22E15-D00C-433C-9F02-014B1F73D183/Documents/myapp.sqlite, NSFilePath=/Users/harikrishnant/Library/Developer/CoreSimulator/Devices/8E531314-F1AE-417F-8E99-7AA92967CDC9/data/Containers/Bundle/Application/0A710929-475D-457C-8D2D-C2F2BBEB6B92/myapp.app/myapp.sqlite, NSUnderlyingError=0x7faffe1b5cf0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

I checked the following path using terminal and figured out that the sqlite file actually exists in the app bundle:

/Users/harikrishnant/Library/Developer/CoreSimulator/Devices/8E531314-F1AE-417F-8E99-7AA92967CDC9/data/Containers/Bundle/Application/0A710929-475D-457C-8D2D-C2F2BBEB6B92/myapp.app/myapp.sqlite

But still I am getting this error. I tried everything. I even cleaned the build folder and reinstalled the application, it still didn't work. What can be the problem here? How to solve it?

Your code is almost correct. It has two flaws with this line:

NSString *destination = [[[Utils applicationDocumentsDirectory] absoluteString] stringByAppendingString:@"myapp.sqlite"];

The use of absoluteString is incorrect. This gives a file URL in the form file://path/to/Documents/ . You need to use the path method to get a file path (not file URL) form the NSURL .

Then you need to properly append the filename to the path. You need to use stringByAppendingPathComponent: instead of stringByAppendingString: .

That line should be:

NSString *destination = [[[Utils applicationDocumentsDirectory] path] stringByAppendingPathComponent:@"myapp.sqlite"];

I use bellow code to copy my SQLite DB from Application Bundle to Document Directory.
NOTE 'Database' is Folder name. 'datasource' is my database name and it's extension is 'db'

-(void)saveDatabase{
        //put bundle database to DocumentDirectory
        NSLog(@"%@",[self databasePath]);
        //Create Path For Destination
        NSString* path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
        path = [path stringByAppendingPathComponent:@"Database"];
        BOOL isExists=[[NSFileManager defaultManager]fileExistsAtPath:path];
        if(!isExists){
            NSError* error;
            BOOL isCreated = [[NSFileManager defaultManager]createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:&error];
            if(isCreated){
                path = [path stringByAppendingPathComponent:@"Datasource"];
                path = [path stringByAppendingPathExtension:@"db"];
                isExists = [[NSFileManager defaultManager]fileExistsAtPath:path];
                if(!isExists){
                    NSError* dbError;
                    NSString* bundle = [[NSBundle mainBundle]pathForResource:@"Datasource" ofType:@"db"];
                    isCreated = [[NSFileManager defaultManager]copyItemAtPath:bundle toPath:path error:&dbError];
                    if(isCreated){
                        NSLog(@"DatabasePath %@",path);
                    }else{
                        NSLog(@"ErrorCopying DB file %@",dbError.localizedDescription);
                    }
                }else{

                }

            }else{
                NSLog(@"Error While Creating Database Directory:->%@",error.localizedDescription);
            }
        }
    }
    - (NSString*)databasePath{
        NSString* path = [self documentDirectory];
        path = [path stringByAppendingPathComponent:@"Database"];
        path = [path stringByAppendingPathComponent:@"Datasource"];
        path = [path stringByAppendingPathExtension:@"db"];
        return path;
    }
    - (NSString*)documentDirectory{
        return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    }

Make sure your file is listed in Build Phases -> Copy Bundle Resources in the target you use. Try deleting Derived data . If still does not work go to Derived data and check the file using Finder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM