【问题标题】:Preload database with CoreData, Swift 4使用 CoreData、Swift 4 预加载数据库
【发布时间】:2018-08-12 14:14:57
【问题描述】:

我尝试在我的应用程序中预加载我的数据库(.sqlite、.sqlite-wal 和 .sqlite-shm),但我不能。

我试试这个:

func preloadDBData()
{
    let sqlitePath = Bundle.main.path(forResource: "leksikonPreload", ofType: "sqlite")
    let sqlitePath_shm = Bundle.main.path(forResource: "leksikonPreload", ofType: "sqlite-shm")
    let sqlitePath_wal = Bundle.main.path(forResource: "leksikonPreload", ofType: "sqlite-wal")

    let URL1 = URL(fileURLWithPath: sqlitePath!)
    let URL2 = URL(fileURLWithPath: sqlitePath_shm!)
    let URL3 = URL(fileURLWithPath: sqlitePath_wal!)
    let URL4 = URL(fileURLWithPath: NSPersistentContainer.defaultDirectoryURL().relativePath + "/leksikonPreload.sqlite")
    let URL5 = URL(fileURLWithPath: NSPersistentContainer.defaultDirectoryURL().relativePath + "/leksikonPreload.sqlite-shm")
    let URL6 = URL(fileURLWithPath: NSPersistentContainer.defaultDirectoryURL().relativePath + "/leksikonPreload.sqlite-wal")

    if !FileManager.default.fileExists(atPath: NSPersistentContainer.defaultDirectoryURL().relativePath + "/leksikonPreload.sqlite") {
        // Copy 3 files
        do {
            try FileManager.default.copyItem(at: URL1, to: URL4)
            try FileManager.default.copyItem(at: URL2, to: URL5)
            try FileManager.default.copyItem(at: URL3, to: URL6)

            print("=======================")
            print("FILES COPIED")
            print("=======================")

        } catch {
            print("=======================")
            print("ERROR IN COPY OPERATION")
            print("=======================")
        }
    } else {
        print("=======================")
        print("FILES EXIST")
        print("=======================")
    }
}

并在我的 appDelegate didFinishLaunchingWithOptions 方法中调用 preloadDBData()。我的核心数据模型的名称:“leksikon”,我的预加载数据的名称:“leksikonPreload”。当“文件已复制”和“文件存在”时,此函数工作正常,并且真正写入,但是当我尝试打印我的数据时 - 我的数组包含 0 个元素,但我确信 leksikonPreload 包含 12 个值。 我的打印代码:

func printData() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let fetchRequest: NSFetchRequest<Word> = Word.fetchRequest()

    do
    {
        let arr = try context.fetch(fetchRequest)
        for obj in arr {
            print(obj.engValue)
            print(obj.rusValue)
            print(obj.was)
        }
    }
    catch
    {
        print(error.localizedDescription)
    }
}

【问题讨论】:

  • 如何在应用委托中初始化持久化容器?默认情况下,它会为模型和商店使用项目名称:您可能需要指定不同的商店名称(除非您的项目称为 leksikonPreload?)

标签: ios swift core-data


【解决方案1】:

我也有同样的问题。

我有一个名为:BenedictusCoreData.sqlite 的 preloadedDataBase

我将它添加到我的项目中。并修改了 AppDelegate:

    lazy var persistentContainer: NSPersistentContainer = {

    let container = NSPersistentContainer(name: "BenedictusCoreData")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {

            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

// MARK: - Preload data from my sqlite file.

func preloadDBData() {

    let sqlitePath = Bundle.main.path(forResource: "BenedictusCoreData", ofType: "sqlite")
    let originURL = URL(fileURLWithPath: sqlitePath!)
    let destinationURL = URL(fileURLWithPath: NSPersistentContainer.defaultDirectoryURL().relativePath + "/BenedictusCoreData.sqlite")

    if !FileManager.default.fileExists(atPath: NSPersistentContainer.defaultDirectoryURL().relativePath + "/BenedictusCoreData.sqlite") {
        // Copy file
        do {
            try FileManager.default.copyItem(at: originURL, to: destinationURL)

            print("=======================")
            print("FILE COPIED")
            print("=======================")

        } catch {
            print("=======================")
            print("ERROR IN COPY OPERATION")
            print("=======================")
        }
    } else {
        print("=======================")
        print("FILE EXIST")
        print("=======================")
    }

}

我只复制了 sqlite 文件,因为我没有 wal 和 shm 文件,而且我只想在文件第一次启动时复制它并且仅用于读取目的。

在 AppDelegate didFinishLaunchingWithOptions 中调用了 preloadDBData() 函数。首次启动时会显示“文件已复制”。在它之后,启动时说“文件存在”。所以看起来文件被复制了。

项目中的模型文件名为 BenedictusCoreData.xcdatamodeld,项目名称为 BenedictusCoreData

在 ViewController 中我写了以下内容:

    var encyclicalsArray = [Encyclicals]()

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    loadItems()

}

func loadItems() {

    let request: NSFetchRequest<Encyclicals> = Encyclicals.fetchRequest()
    do {
        try encyclicalsArray = context.fetch(request)
        for encyclical in encyclicalsArray {
            print(encyclical.titulo_es!)
            print(encyclical.date!)
            print(encyclical.idURL!)
        }
    } catch {
        print("Error fetching encyclicals: \(error)")
    }

}

而且它什么也不打印。但是,我的 sqlite 预加载文件在此表中有三个条目。

【讨论】:

    猜你喜欢
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多