Swift:无法预加载Coredata

时间:2015-01-08 13:18:24

标签: objective-c sqlite core-data swift xcode6

当我在“目标 - 构建阶段 - 复制捆绑资源”下包含带有Objective-C的SQLite文件时,该文件将完全复制到目标,即设备或模拟器。在目标上,我得到整个文件:表和内容(记录/行)。

对Swift执行相同的操作,表将被复制,但它们是空的:没有记录/行。 : - (

我可以做些额外的事吗?有没有“技巧”?

如何使用Swift预加载带有基本记录的核心数据?

我正在使用Xcode v6.1.1,Beta 6.2也是如此。

3 个答案:

答案 0 :(得分:4)

这是我的解决方案(对于sqlite文件)。我不知道为什么它在Swift中如此“奢侈”。也许有一种更简单的方法? 很多THX到pbasdf !!!

重要:* .sqlite文件下方必须将* .sqlite-shm和* .sqlite-wal添加到项目中 此文件将自动添加到“目标 - 构建阶段 - 复制捆绑资源”

这是基于“AppDelegate.swift”的标准模板 ......

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
    // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
    // Create the coordinator and store
    var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)

    let dataName = „MyData.sqlite" // must be replaced by the name of your file!
    let modelName = „MyData“ // must be replaced by the name of your model!

    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent(dataName)

    let fileManager = NSFileManager.defaultManager()
    let bundle = NSBundle.mainBundle()
    let fromURL = bundle.URLForResource(modelName, withExtension: "sqlite")

    // check sqlite-file: must it be installed?
    if !fileManager.fileExistsAtPath(url.path!) {
        self.copySqlliteFiles(modelName, databaseName: dataName)
    }

    var error: NSError? = nil
    var failureReason = "There was an error creating or loading the application's saved data."

    if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options:  nil, error: &error) == nil {

...}

   return coordinator
}()

// MARK: - copy sqllite-files (c) by Ray Wenderlich & Team in „“Core Data by Tutorials“

// check sqlite-files: they must be installed...
func copySqlliteFiles(modelName: String, databaseName: String)
{
    let bundle = NSBundle.mainBundle()

    let baseDatabaseURL = bundle.URLForResource(modelName, withExtension: "sqlite")
    let documentsURL = self.applicationDocumentsDirectory
    let storeURL = documentsURL.URLByAppendingPathComponent(databaseName)
    NSFileManager.defaultManager().copyItemAtURL(baseDatabaseURL!, toURL: storeURL,error: nil)

    let baseSHMURL = bundle.URLForResource(modelName,withExtension: "sqlite-shm")
    let shmURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent(databaseName + "-shm")
    NSFileManager.defaultManager().copyItemAtURL(baseSHMURL!, toURL: shmURL, error: nil)

    let walURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent(databaseName + "-wal")
    let baseWALURL = bundle.URLForResource(modelName, withExtension: "sqlite-wal")
    NSFileManager.defaultManager().copyItemAtURL(baseWALURL!, toURL: walURL, error: nil)
}

答案 1 :(得分:0)

我认为这可能与文件在iOS上的布局有关。具体做法是:

  1. 复制源文件时(通过Xcode或在安装时),它将被放入应用程序包/容器目录(只读)
  2. 标准CoreData初始化代码在Documents目录中查找数据存储。
  3. 找不到您的源数据(因为它位于错误的位置),CoreData会创建一个新的空存储。
  4. 要解决此问题,您需要将商店从Application目录复制到Documents目录(如果它尚不存在)。

    这个link给出了解释和示例代码。但在Objective-C中它看起来像:

    NSString *storePath = [[self applicationDocumentsDirectory] 
        stringByAppendingPathComponent: @"MyDB.sqlite"];
    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
    
    // Copy the default db if it doesn't already exist
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:storePath]) {
        NSString *defaultStorePath = [[NSBundle mainBundle] 
            pathForResource:@"MyDB" ofType:@"sqlite"];
        if (defaultStorePath) {
            [fileManager copyItemAtPath:defaultStorePath 
    toPath:storePath error:NULL];
        }
    }
    

答案 2 :(得分:0)

我遇到了与此相关的相关问题。我开始研究一些使用这一行的教程:

documentsURL.URLByAppendingPathComponent("StoreName")

在某些时候,这停止了工作。数据不再写入商店。为了查看为什么没有写入数据,我尝试打开sqlite文件但是在我的mac上找不到它正在使用的URL。 app文件夹在那里,但没有sqlite文件。我回顾了较旧的核心数据项目,发现他们使用了.sqlite扩展。所以我将该行修改为:

documentsURL.URLByAppendingPathComponent("StoreName.sqlite")

这似乎有效,所以试一试。