使用预先填充的Core Data部署应用程序

时间:2017-12-19 18:07:37

标签: swift sqlite core-data

我尝试在已安装Core Data的情况下发送我的应用。我找到了一些链接,他们解释了如何做,但要么它没有工作,要么答案很老。我关注this帖子,但它不起作用。解决方案可能是将.sqlite文件导入app文件夹,然后将其复制到设备的文件系统,但我无法弄清楚如何操作。有没有办法用现有的实体和记录预先填充我的核心数据?

3 个答案:

答案 0 :(得分:1)

这是我找到的解决方案:

第1步
在另一个应用中填充Core Data并使用以下代码获取文件路径:

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

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

<强>步骤3
创建功能以检查应用程序的首次运行。

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
}

<强>步骤4
将其复制到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
}()

第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)")
    }
}

答案 1 :(得分:0)

我推荐以下教程。它说明了如何实现。

https://www.youtube.com/watch?v=xcV8Ow9nWFo

答案 2 :(得分:0)

我的步骤 4 版本:

  private func isFirstLaunch() -> Bool {
    let isFirstLaunchKey = "firstLaunch"
    let userDefaults = UserDefaults.standard
    let isFirstLaunch = !userDefaults.bool(forKey: isFirstLaunchKey)
    
    if isFirstLaunch { userDefaults.setValue(true, forKey: isFirstLaunchKey) }
    return isFirstLaunch
  }

  lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "YourProjectCDName")
    
    if isFirstLaunch() {
      if let storeUrl = container.persistentStoreDescriptions.first?.url,
         let seededDataUrl = Bundle.main.url(forResource: "YourProjectCDName", withExtension: "sqlite") {
        do {
          try container.persistentStoreCoordinator.replacePersistentStore(
            at: storeUrl,
            destinationOptions: nil,
            withPersistentStoreFrom: seededDataUrl,
            sourceOptions: nil,
            ofType: NSSQLiteStoreType)
        } catch {
          print(error.localizedDescription)
        }
      } else {
        fatalError("Cannot unwrap URLs!")
      }
    }
    
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
      if let error = error as NSError? {
        fatalError("Unresolved error \(error), \(error.userInfo)")
      }
    })
    return container
  }()