尝试从bundle复制到文档目录时出错

时间:2016-03-26 08:36:08

标签: ios objective-c nsfilemanager nsbundle

我已将sqlite文件添加到我的应用程序中,并尝试将其从捆绑包复制到文档目录。我也将sqlite添加到目标应用程序中。以下是我用来复制文件的代码:

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) {
            //
        }
    }

[Utils applicationDocumentsDirectory]的代码:

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

但是当执行此代码时,我得到以下error

  

错误域= NSCocoaErrorDomain代码= 4“文件”myapp.sqlite“   不存在。“   的UserInfo = {NSSourceFilePathErrorKey = /用户/ harikrishnant /库/开发商/ CoreSimulator /设备/ 8E531314-F1AE-417F-8E99-7AA92967CDC9 /数据/容器/捆绑/应用/ 0A710929-475D-457C-8D2D-C2F2BBEB6B92 / myapp.app / myapp.sqlite,   NSUserStringVariant =(       复制),NSDestinationFilePath = file:/// Users / harikrishnant / Library / Developer / CoreSimulator / Devices / 8E531314-F1AE-417F-8E99-7AA92967CDC9 / data / Containers / Data / Application / 13B22E15-D00C-433C-9F02-014B1F73D183 /文件/ myapp.sqlite,   NSFilePath = /用户/ harikrishnant /库/开发商/ CoreSimulator /设备/ 8E531314-F1AE-417F-8E99-7AA92967CDC9 /数据/容器/捆绑/应用/ 0A710929-475D-457C-8D2D-C2F2BBEB6B92 / myapp.app / myapp.sqlite ,   NSUnderlyingError = 0x7faffe1b5cf0 {错误域= NSPOSIXErrorDomain   代码= 2“没有这样的文件或目录”}}

我使用终端检查了以下路径,并发现sqlite文件实际存在于应用包中:

  

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

但我仍然收到此错误。我尝试了一切。我甚至清理了构建文件夹并重新安装了应用程序,它仍然无法正常工作。这可能是什么问题?怎么解决?

3 个答案:

答案 0 :(得分:5)

您的代码几乎是正确的。这条线有两个缺点:

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

absoluteString的使用不正确。这会以file://path/to/Documents/的形式提供文件网址。您需要使用path方法从NSURL获取文件路径(而非文件URL)。

然后,您需要将文件名正确附加到路径。您需要使用stringByAppendingPathComponent:代替stringByAppendingString:

那一行应该是:

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

答案 1 :(得分:0)

我使用下面的代码将我的SQLite DB从Application Bundle复制到Document Directory 注意'数据库'是文件夹名称。 'datasource'是我的数据库名称,它的扩展名是'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"];
    }

答案 2 :(得分:0)

确保您的文件列在您使用的目标中的Build Phases -> Copy Bundle Resources中。尝试删除Derived data。如果仍然无效,请转到Derived data并使用Finder检查文件。