简体   繁体   English

无法将sqlite文件从应用程序捆绑包复制到文档目录:正在获取(可可错误260)

[英]Unable to copy sqlite file from app bundle to documents directory: getting (Cocoa error 260)

I am trying to copy my sqlite file from app bundle into documents directory using the code below 我正在尝试使用以下代码将我的sqlite文件从应用程序捆绑包复制到文档目录中

-(id)init {

    self = [super init];
    if (self) {

// 1. Create a handle to the database file for UIManagedDocument // 1.为UIManagedDocument创建数据库文件的句柄

        NSURL *docURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        docURL = [docURL URLByAppendingPathComponent:@"DefaultDatabase"];
        self.document =  [[UIManagedDocument alloc] initWithFileURL:docURL]; // URL of the location of document i.e. /documents directory
    NSLog(@" URL document");

        //set our document up for automatic migrations

        if (self.document) {
            NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES],
            NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES],
            NSInferMappingModelAutomaticallyOption, nil];

            self.document.persistentStoreOptions = options;

            // Register for Notifications

            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(objectsDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.document.managedObjectContext];

            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.document.managedObjectContext];
        } else {         
            NSLog(@"The UIManaged Document could not be initialized");

        }

// 2. Check if the persistent store file does not exists in case of first run // 2.在第一次运行的情况下检查持久性存储文件是否不存在

    if (!([[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]])) {
        NSLog(@" persistent file not found trying to copy from app bbundle");
        NSString *docFileName = [UIManagedDocument persistentStoreName];
        NSString *docFilePath = [[NSBundle mainBundle] pathForResource:docFileName ofType:@"sqlite"];
        **NSLog(@" doc file path = %@", docFilePath);**
        if (docFilePath) { // found the database file in app bundle
            NSLog(@" found file in bundle");
            //Production: Copy from app bundle.
            NSError *error = nil;
            NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *copyToPath  = [searchPaths lastObject];
            if([[NSFileManager defaultManager] copyItemAtPath:docFilePath toPath:copyToPath error:&error]){
                NSLog(@"File successfully copied");
            } else { // if could not locate the file
                [[[UIAlertView alloc]initWithTitle:NSLocalizedString(@"error", nil) message: NSLocalizedString(@"failedcopydb", nil)  delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", nil)  otherButtonTitles:nil] show];
                NSLog(@"Error description-%@ \n", [error localizedDescription]);
                NSLog(@"Error reason-%@", [error localizedFailureReason]);
            }
        }
    }
}
return self;

} }

a) I created the .sqlite file using data loader app which uses UIManagedDcoument to add data to Core Data. a)我使用数据加载器应用程序创建了.sqlite文件,该应用程序使用UIManagedDcoument将数据添加到核心数据。 The .sqlite file gets generated in documents directory. .sqlite文件在documents目录中生成。

b) I add the *.sqlite file to resources folder and add it to bundle. b)我将* .sqlite文件添加到资源文件夹,并将其添加到包中。 If I check the app bundle using Terminal..I see 'persistent store' and <app name.momd> file under the bundle directory. 如果我使用终端机检查应用程序捆绑包, <app name.momd>在捆绑包目录下看到“持久存储”和<app name.momd>文件。 There is no file with extension .sqlite 没有扩展名为.sqlite的文件

c)But in my code above when I check for whether files exists in app bundle using line of code, it is successful. c)但是在上面的代码中,当我使用代码行检查应用程序捆绑包中是否存在文件时,它是成功的。 So file exists in bundle 所以文件存在于包中

   NSString *file = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];

d) But when try to copy, it fails and gives me (Cocca Error 206) meaning its unable to find the .sqlite file in the app bundle. d)但是,当尝试复制时,它失败并显示我错误信息(Cocca错误206),这意味着它无法在应用程序包中找到.sqlite文件。

  if([[NSFileManager defaultManager] copyItemAtPath:file toPath:copyToPath error:&error])

which is in line with the fact that I don't see .sqlite file under app bundle directory instead I see a persistent store and .momd files. 这符合以下事实:我在应用程序捆绑包目录下没有看到.sqlite文件,而是看到了持久存储和.momd文件。

So where I am going wrong ? 那么我要去哪里错了?

EDIT 编辑

This is an explanation of how I am generating my mydata.sqlite file. 这是有关如何生成mydata.sqlite文件的说明。

I am using Core Data and want to provide a pre-poulated database upon first launch of app to the user. 我正在使用Core Data,并希望在首次向用户启动应用程序时提供一个预先填充的数据库。 So I used a data loader app to create .sqlite file for me. 因此,我使用数据加载器应用程序为我创建了.sqlite文件。 I am using UIManagedDocument for core data. 我正在使用UIManagedDocument作为核心数据。 After I run the app, I see a mydata.sqlite directory gets created under documents directory. 运行该应用程序后,我看到在documents目录下创建了一个mydata.sqlite目录。 The directory structure is as follows 目录结构如下

/users//.../documents/mydata.sqlite/storeContent/persistenStore. /users//.../documents/mydata.sqlite/storeContent/persistenStore。

So basically instead of creating a file, it creates a directory with .sqlite extension and I see persistentStore file. 因此,基本上,它不是创建文件,而是创建带有.sqlite扩展名的目录,并且我看到了persistentStore文件。 So when I try to copy resources under app bundle in target under build phases..it adds the persistentStore and not .sqlite file. 因此,当我尝试在构建阶段在目标中的应用程序包下复制资源时,它会添加persistentStore而不是.sqlite文件。

My question whatever is described is correct and I am supposed to handle it differently in my code. 我的问题无论描述如何都是正确的,应该在我的代码中以不同的方式处理。 If yes, what is that I am supposed to do to get handle on data store. 如果是,我应该怎么做才能处理数据存储。

I thought .sqlite was a file and not a directory. 我以为.sqlite是文件而不是目录。 Please guide 请指导

Thanks 谢谢

This line does not actually check if the file exists: 该行实际上并不检查文件是否存在:

NSString *file = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];

All that does is build the path in file . 所有要做的就是在file构建路径。 If you want to check whether it exists, you need to use [NSFileManager fileExistsAtPath:] . 如果要检查是否存在,则需要使用[NSFileManager fileExistsAtPath:] Or you could go back to using pathForResource:ofType: , which was apparently correct when it returned nil . 或者,您可以返回使用pathForResource:ofType:当它返回nil时,这显然是正确的。

You don't seem to be copying the file into the bundle at all. 您似乎根本没有将文件复制到捆绑软件中。 This is a problem with your Xcode project configuration. 这是您的Xcode项目配置存在的问题。

I read up apple documentation on UIManagedDocument and here are the key points that I was going wrong on 我在UIManagedDocument上阅读了苹果文档 ,这是我犯错的关键点

  1. Was handling UIManagedDocument incorrectly. 错误地处理了UIManagedDocument。 When you initialize a managed document, you specify the URL for the document location. 初始化托管文档时,请指定文档位置的URL and not the document itself. 而不是文档本身。 If you need to add 如果需要添加

  2. You can perform additional customization by creating a subclass of UIManagedDocument ie Override persistentStoreName to customize the name of the persistent store file inside the document's file package. 您可以通过创建UIManagedDocument的子类(即OverridepersistentStoreName)来执行其他自定义,以自定义文档文件包中的持久性存储文件的名称。

  3. cutting and pasting the example code for the right way to handle the data file 剪切和粘贴示例代码以正确的方式处理数据文件

You create a managed document object using initWithFileURL:; 您可以使用initWithFileURL:创建一个托管文档对象: if you want, you can then configure the document before you use its managed object context. 如果需要,可以在使用文档的受管对象上下文之前对其进行配置。 Typically you might set the persistent store options, as illustrated in this example: 通常,您可以设置持久性存储选项,如本示例所示:

NSURL *docURL = [[self applicationDocumentsDirectory]        URLByAppendingPathComponent:@"FirstDocument"];
 doc = [[UIManagedDocument alloc] initWithFileURL:docURL];

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
doc.persistentStoreOptions = options;


**if ([[NSFileManager defaultManager] fileExistsAtPath:[docURL path]]**) {
   [doc openWithCompletionHandler:^(BOOL success){
    if (!success) {
        // Handle the error.
    }
    }];
 }
  else {
   [self addInitialData];
   [doc saveToURL:docURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){
      if (!success) {
        // Handle the error.
     }
     }];
    } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法在 iOS 应用程序中加载文件; Cocoa 错误 260 - Unable to load file in iOS app; Cocoa error 260 无法将文件从bundle复制到Documents目录,为什么fileExistsAtPath会返回错误? - Unable to copy file from bundle to Documents directory, why does fileExistsAtPath return error? 有时将文件包中的错误复制到iOS中的文档目录 - Sometime ERROR copy file from bundle to documents directory in iOS 无法在核心资料中建立唯读的sqlite储存库:Cocoa错误260 - Unable to create a readonly sqlite store in Core Data: Cocoa Error 260 尝试从分发包复制到文档目录时出错 - Error trying to copy from bundle to documents directory 无法将文件从捆绑包复制到iOS中的文档目录 - Can`t copy file from bundle to documents directory in iOS 无法将文件从捆绑包复制到文档目录子文件夹 - Failing to copy file from Bundle to Documents Directory Subfolder 将文件从主捆绑包复制到文档目录(沙箱) - Copy file to documents directory (sandbox) from main bundle 如何将文件从Documents Directory复制到应用程序捆绑包? - How to copy a file from Documents Directory to application bundle? 如何使用Cordova将文件从应用程序捆绑包复制到Documents文件夹? - How to copy a file from app bundle to the Documents folder with Cordova?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM