ios App Bundle中包含的核心数据存储

efzxgjgh  于 2023-04-22  发布在  iOS
关注(0)|答案(4)|浏览(111)

我无法在Apple文档中找到这些步骤的明确描述...
1.我的xcode项目中有一个xcdatamodeld
1.在启动时,我的应用程序解析XML(项目资源)以填充核心数据存储(SQLLite)
1.在我的应用生命周期内,我添加、删除、更新该应用商店的数据
现在,我想停止在设备上执行繁重的XML解析过程,直接包含一个包含所需数据的Store。
我对此有一些疑问:

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

感谢您的提示。网址或其他SO问题将非常感谢!
赫罗

pcww981p

pcww981p1#

你可以在你的应用中包含store文件(大多数情况下是sqlite db)。然后在你的应用委托中编辑persistentStoreCoordinator getter方法:

- (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_;
}
ct3nt3jp

ct3nt3jp2#

1.使用应用程序的数据模型和类编写实用程序。使用实用程序应用程序从XML提供的数据生成持久存储。
1.将商店文件像任何其他资源一样添加到应用程序包
1.在应用程序目录中选择一个位置,您希望活动商店驻留在该位置,例如Library目录。
1.在启动时,让应用检查存储是否存在于目录中。如果不存在,应用应该使用标准NSFileManger方法将存储从应用包复制到目录中,就像任何其他文件一样。(通常,您只需要在第一次创建存储时执行此操作。)
这就是它的全部。

y1aodyip

y1aodyip3#

您当前正在做的(在首次启动时填充)是填充Core Data存储的“推荐”方式。虽然有点黑客,但您可以如下所示为设备上的数据库播种:
1.在模拟器中启动应用
1.执行模拟器应用程序填充Core Data存储所需的任何操作
1.停止模拟器应用程序
1.导航到模拟的Documents文件夹(类似于~/Library/Application Support/iPhone Simulator/4.3/Applications/335567A0-760D-48AF-BC05-7F0D9BD085B6/<app-name>.app/
1.找到sqlite数据库(它具有初始化CoreData时所指定的名称)
1.将此数据库复制到项目中,并将其添加为要复制的资源
1.在application:didFinishLaunchingWithOptions:方法中添加一些代码,以便在第一次启动时,它将数据库从只读资源目录复制到应用的文档目录。当然,您需要在初始化Core Data之前**执行此操作。
然而,根据您在数据库中存储的内容,您可能会发现big-vs. little-endianness问题或其他不兼容性。(splite3 databasefile .dump >dumpfile),然后将转储文件包含在项目中(如上所述),并在第一次启动时在应用程序中slurp转储(逐行阅读它,并将sql语句交给sqlite API)。

oiopk7p5

oiopk7p54#

对于更新的Swift 5答案,遵循与上述相同的主题(即)
1.从另一个地方将数据填充到核心数据sqlite DB中。
1.将创建的数据库包含在应用程序包中。
1.在应用程序启动时,检查该文件是否在Application Support文件夹中,如果不在,则将种子数据库移到那里。
下面是相关的swift代码,我将我的代码放在持久性控制器的共享示例的静态初始化器中,但请按照您的意愿使用它。

static func seedDataIfRequired() {
    let dbname = "your file name here"
    if let appSupportDirURL : URL = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first {
        let appSupportDir = appSupportDirURL.path(percentEncoded:false)
        if FileManager.default.fileExists(atPath: "\(appSupportDir)\(dbname).sqlite") {
            debugPrint("Core data database exists, no action needed.")
        }else {
            if let seedDatabasePath = Bundle.main.path(forResource: "\(dbname)", ofType: "sqlite") {
                debugPrint("Seed database is available.")
                // move it there
                try? FileManager.default.createDirectory(atPath: appSupportDir, withIntermediateDirectories: true)
                let status = FileManager.default.secureCopyItem(at:URL(filePath: seedDatabasePath) , to: URL(filePath: "\(appSupportDir)\(dbname)"))
                if status == true {
                    debugPrint("Seed database COPIED.")
                }else{
                    debugPrint("Seed database copy FAILURE.")
                }
            }
        }
    }
}

相关问题