【问题标题】:Core Data Store included in App BundleApp Bundle 中包含的 Core Data Store
【发布时间】:2011-08-03 17:38:31
【问题描述】:

我在 Apple 文档中找不到这些步骤的清晰描述...

  1. 我的 xcode 项目中有一个 xcdatamodeld
  2. 在启动时,我的应用程序会解析 XML(项目资源)以填充 Core Data Store (SQLLite)
  3. 在我的应用程序的生命周期中,我添加、删除、更新该商店的数据

现在,我想停止在设备上执行繁重的 XML 解析过程,并直接包含一个包含所需数据的 Store。

我对此有一些疑问:

  • 我可以用 OS X 应用程序填充商店,然后将此商店包含在我的 XCode-iOs 项目中吗?
  • 我的商店没有出现在 Xcode 中。实际上它是在运行时创建的。如何在项目中添加商店并将其链接到我的 xcdatamodeld ?
  • 我已经读到这样做会阻止我的商店可写...我想我必须在启动时将它复制到正确的位置(Core Data 实用程序教程对此很有帮助)。我说的对吗?

感谢您的提示。 URL 或其他 SO 问题将不胜感激!

克洛德

【问题讨论】:

    标签: ios objective-c core-data deployment persistence


    【解决方案1】:

    您可以在您的应用程序中包含存储文件(大多数情况下是 sqlite db)。 然后在您的应用委托中编辑 persistentStoreCoordinator getter merhod:

    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    
        if (persistentStoreCoordinator_ != nil) {
            return persistentStoreCoordinator_;
        }
    
        NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"CoreDataStore.sqlite"];
    
        // Check if the store exists in. 
        if (![[NSFileManager defaultManager] fileExistsAtPath:storePath]) {
            // copy the payload to the store location.
            NSString *bundleStore = [[NSBundle mainBundle] pathForResource:@"YourPayload" ofType:@"sqlite"];
    
            NSError *error = nil;
            [[NSFileManager defaultManager] copyItemAtPath:bundleStore toPath:storePath error:&error];
    
            if (error){
                NSLog(@"Error copying payload: %@", error);
            }
        }
    
        NSError *error = nil;
        NSURL *storeURL = [NSURL fileURLWithPath:storePath];
        persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
        if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }    
    
        return persistentStoreCoordinator_;
    }
    

    【讨论】:

    • 感谢您的代码。您不认为设备/核心数据/复制数据库之间可能存在兼容性问题吗?
    • 不,我主要是用模拟器创建db,然后在设备上使用,没有问题。
    • 在您回答的第二句话中,persantstore 是什么? (错字?)
    【解决方案2】:
    1. 使用应用程序的数据模型和类编写实用程序应用程序。使用实用程序应用从 XML 提供的数据生成持久存储。
    2. 像任何其他资源一样将商店文件添加到应用程序包中
    3. 在应用目录中选择您希望活动商店驻留的位置,例如库目录。
    4. 在启动时让应用程序检查商店是否存在于目录中。如果不是,应用程序应该使用标准 NSFileManger 方法将应用程序包中的商店复制到目录,就像任何其他文件一样。 (通常,您只需在第一次创建商店时执行此操作。)

    这就是它的全部内容。

    【讨论】:

    • 如果我将sqlite文件保存在Bundle中可以吗,因为它是只读的??
    • Core Data 将希望在应用程序的应用程序支持目录中找到 sqlite 文件:try FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: false) 是获取此文件的一种方法。但是,如果您正在预加载数据库,可以保留捆绑包中文件的副本以复制到应用程序支持。 -- 哎呀,这当然是 Swift,因为它是几年后的 ;-)
    【解决方案3】:

    您目前正在做的(在首次启动时填充)是填充核心数据存储的“推荐”方式。尽管它有点骇人听闻,但您可以按如下方式为设备上的数据库播种:

    1. 在模拟器中启动您的应用
    2. 为模拟器应用程序执行您需要做的任何事情来填充核心数据存储
    3. 停止模拟器应用
    4. 导航到模拟的 Documents 文件夹(类似于 ~/Library/Application Support/iPhone Simulator/4.3/Applications/335567A0-760D-48AF-BC05-7F0D9BD085B6/<app-name>.app/
    5. 找到 sqlite 数据库(它有你在初始化 Core Data 时给它的名字)
    6. 将此数据库复制到您的项目中,并将其添加为要复制的资源
    7. 向您的application:didFinishLaunchingWithOptions: 方法添加一些代码,以便在首次启动时,它将数据库从只读资源目录复制到应用程序的文档目录。当然,您需要初始化 Core Data 之前执行此操作。

    根据您在数据库中存储的确切内容,您可能会发现大端与小端的问题或其他不兼容问题。为了使该方法更安全一些,您可以将模拟器数据库 (splite3 databasefile .dump >dumpfile) 转储到您的 Mac 上,然后将转储文件包含在您的项目中(如上),并在您的应用程序中首次启动时啜饮转储(阅读它的行- by-line,并将 sql 语句交给 sqlite API)。

    【讨论】:

    • 好的。似乎使用 SQL 转储和 parse+fill 是一个好方法。但是处理 XML 并没有那么复杂(我认为)。此外,我通过网络接收 XML 数据,我需要对其进行解析。我将保持我的 XML 机制不变...感谢您的帮助,我以后可以使用它 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 2021-03-24
    • 2015-02-08
    • 1970-01-01
    • 2021-06-30
    • 2020-07-26
    相关资源
    最近更新 更多