使用预填充的核心数据部署应用程序

And*_*oso 5 sqlite core-data swift

我正在尝试发送Core Data已经填充的应用程序。我找到了一些链接,其中解释了如何执行此操作,但要么不起作用,要么答案非常旧。我关注了这篇文章,但它不起作用。解决方案可能是将.sqlite文件导入到应用程序文件夹,然后将它们复制到设备的文件系统,但我不知道该怎么做。有没有什么方法可以用现有实体和记录预先填充我的核心数据?

And*_*oso 4

这是我找到的解决方案:

步骤 1
在另一个应用程序中 填充您的内容Core Data并使用以下代码获取文件路径:

let paths = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
print(documentsDirectory)
Run Code Online (Sandbox Code Playgroud)

第2步
将您的3个带有.sqlite扩展名的文件拖到您的xCode项目中。(请务必选择Add to targets选项)。

Step3
创建函数来检查应用程序的首次运行。

func isFirstLaunch() -> Bool {
    let hasBeenLaunchedBeforeFlag = "hasBeenLaunchedBeforeFlag"
    let isFirstLaunch = !UserDefaults.standard.bool(forKey: hasBeenLaunchedBeforeFlag)
    if (isFirstLaunch) {
        UserDefaults.standard.set(true, forKey: hasBeenLaunchedBeforeFlag)
        UserDefaults.standard.synchronize()
    }
    return isFirstLaunch
}
Run Code Online (Sandbox Code Playgroud)

第四步
将其复制到AppDelegate

func getDocumentsDirectory()-> URL {
    let paths = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
    let documentsDirectory = paths[0]
    return documentsDirectory
}

// MARK: - Core Data stack

lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "ProjectName")

    let appName: String = "ProjectName"
    var persistentStoreDescriptions: NSPersistentStoreDescription

    let storeUrl = self.getDocumentsDirectory().appendingPathComponent("FileName.sqlite")

    if UserDefaults.isFirstLaunch() {
        let seededDataUrl = Bundle.main.url(forResource: "FileName", withExtension: "sqlite")
        try! FileManager.default.copyItem(at: seededDataUrl!, to: storeUrl)
    }

    let description = NSPersistentStoreDescription()
    description.shouldInferMappingModelAutomatically = true
    description.shouldMigrateStoreAutomatically = true
    description.url = storeUrl

    container.persistentStoreDescriptions = [description]

    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()
Run Code Online (Sandbox Code Playgroud)

步骤 5
如果您想删除新Core Data文件,请使用此功能:

func deleteFiles() {
    let fileManager = FileManager.default
    let documentsUrl =  FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first! as NSURL
    let documentsPath = documentsUrl.path

    do {
        if let documentPath = documentsPath {
            let fileNames = try fileManager.contentsOfDirectory(atPath: "\(documentPath)")
            print("all files in cache: \(fileNames)")
            for fileName in fileNames {
                if (fileName.contains("YourFileName")) {
                    let filePathName = "\(documentPath)/\(fileName)"
                    try fileManager.removeItem(atPath: filePathName)
                }
            }
            let files = try fileManager.contentsOfDirectory(atPath: "\(documentPath)")
            print("all files in cache after deleting images: \(files)")
        }
    } catch {
        print("Could not clear temp folder: \(error)")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我错了,请纠正我,但是这个解决方案不会重复应用程序用于数据的磁盘空间量吗?从资源包中获取种子数据,然后将其注入到核心数据数据库中。该数据现在位于磁盘上的两个位置。如果我要部署一个包含 250Mb 数据的应用程序,我不想在磁盘上复制这些数据。 (3认同)