在MagicalRecord中使用现有的SQLite数据库(swift)

时间:2014-09-09 09:10:13

标签: ios sqlite core-data swift magicalrecord

我希望我的iOS swift应用程序在MagicalRecord中预加载现有的sqlite文件。
参考this 和其他人,
将sqlite,sqlite-shm,sqlite-wal文件添加到我的项目中,在didFinishLaunchingWithOption中编写了一些代码。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    //  copy initial sqlite file to application directory
    let preloadSQLiteURL:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("myData", ofType: "sqlite")!)
    let preloadShmURL:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("myData", ofType: "sqlite-shm")!)
    let preloadWalURL:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("myData", ofType: "sqlite-wal")!)

    let storeSQLiteURL:NSURL = NSPersistentStore.MR_urlForStoreName("myData.sqlite")
    let storeShmURL:NSURL = NSPersistentStore.MR_urlForStoreName("myData.sqlite-shm")
    let storeWalURL:NSURL = NSPersistentStore.MR_urlForStoreName("myData.sqlite-wal")

    if !NSFileManager.defaultManager().copyItemAtURL(preloadSQLiteURL, toURL: storeSQLiteURL, error:&err) {
        println("failed to copy sqlite file.")
    }
    if !NSFileManager.defaultManager().copyItemAtURL(preloadShmURL, toURL: storeShmURL, error:&err) {
        println("failed to copy shm file.")
    }
    if !NSFileManager.defaultManager().copyItemAtURL(preloadWalURL, toURL: storeWalURL, error:&err) {
        println("failed to copy wal file.")
    }
    MagicalRecord.setupCoreDataStackWithAutoMigratingSqliteStoreNamed("myData.sqlite")

    return true
}

但copyItemAtURL全部失败。

路径的价值就是这些 preloadSQLiteURL = file:///var/mobile/Applications/XXX/myApp.app/myData.sqlite
preloadShmURL = file:///var/mobile/Applications/XXX/myApp.app/myData.sqlite-shm
preloadWalURL = file:///var/mobile/Applications/XXX/myApp.app/myData.sqlite-wal
storeSQLiteURL = file:///var/mobile/Applications/XXX/Documents/myData.sqlite
storeShmURL = file:///var/mobile/Applications/XXX/Documents/myData.sqlite-shm
storeWalURL = file:///var/mobile/Applications/XXX/Documents/myData.sqlite-wal

我的环境是Xcode6 beta7,iOS7.1.3。 有人请帮帮我吗?我该怎么办? 任何建议表示赞赏提前谢谢。

2 个答案:

答案 0 :(得分:2)

结果,自我解决。

NSError显示“操作无法完成。(可可错误516)”
可可错误516是“NSFileWriteFileExistsError”意味着“您无法将文件移动到文件已存在的位置。”

所以,我用这种方式纠正了我的代码。

let fileManager = NSFileManager.defaulManager()
let preloadSQLiteURL:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("myData", ofType: "sqlite")!)
let storeSQLiteURL:NSURL = NSPersistentStore.MR_urlForStoreName("myData.sqlite")
if fileManager.fileExistsAtPath(storeSQLiteURL.path!) {
    // file already exists, delete it and try again.
    fileManager.removeItemAtURL(storeSQLiteURL, error:&err)
}
fileManager.copyItemAtURL(preloadSQLiteURL, toURL:storeSQLiteURL, error:nil)

然后,copyItemAtURL成功完成并且sqlite文件生效。

答案 1 :(得分:0)

虽然这是一个措辞不好的问题,但我假设您要将应用程序包中的SQLite数据库文件加载到用户的文档目录中,这样您就可以从该数据开始,然后从那里更新。

然而,您在正确的路径上,而不是复制所有3个文件,在创建默认数据存储文件时,使用NSSQLitePragmasOption将journal_mode设置为“DELETE”:

NSDictionary *options = @{NSSQLitePragmasOption: @{@"journal_mode": @"DELETE"}}

在创建默认数据集时将持久存储添加到协调器时使用这组选项只会创建一个SQLite文件。从那里开始,只复制一个文件会更容易。

我还在你的代码中注意到你正在复制myData.sqlite,但你正在尝试加载“acData.sqlite”。您是否尝试加载不存在的文件?