应用间数据迁移(将数据迁移到新的应用版本)

时间:2018-06-20 20:12:59

标签: swift sqlite ionic-framework core-data migration

我目前在Apple的App Store中有一个Swift iOS应用。我有很多用户,我想制作一个新版本,并帮助当前用户迁移到新版本。仅供参考:新版本是Ionic应用程序。

从数据角度看,我的应用程序使用的是Core Data,而没有任何iCloud或同步支持。它包含JSON数据以及多个图像。因此,我需要捆绑当前数据,并找到一种将其引入新的ionic应用程序版本的方法。

基本上我的问题是:是否可以在应用程序的documents目录中进行写入,并让新版本抓取该文件以导入其数据?是否可以让两个应用程序传输除AirDrop或自定义URL之外的其他数据?

我不想远程上传数据,我想在设备上本地且无缝地完成所有操作,因此用户不必手动执行任何操作。

欢迎提出建议,谢谢!

3 个答案:

答案 0 :(得分:2)

我建议使用应用程序组来获取共享容器。我对Ionic不熟悉,但这在本机Swift中非常简单。它允许多个应用或扩展程序访问共享的数据容器,如下图所示:

enter image description here

(来自https://agostini.tech/2017/08/13/sharing-data-between-applications-and-extensions-using-app-groups/的图片)


这将需要对现有应用程序进行更新以将数据复制到共享容器,然后用户将不得不在仍旧安装旧应用程序的同时安装新应用程序,因为在没有安装应用程序的情况下,共享容器将被删除使用它。

可以这样设置:

1:在项目的“功能”标签中启用应用组(针对两个应用)。

2:添加一个新的应用程序组,并将其命名为"group.appDomain.appName"或类似名称。

3:现在已经设置了应用程序组,它的共享容器可以通过多种方式使用(用户默认值,NSCoding或核心数据)。


用于共享的用户默认设置

let defaults = UserDefaults.init(suiteName: "group.appDomain.appName")
defaults.set("Example", forKey: "exampleKey")   
defaults.synchronize()

Apple here的更多信息。


对于NSCoding

let sharedContainerDirectory: URL = FileManager().containerURL(forSecurityApplicationGroupIdentifier: "group.appDomain.appName")!

let sharedArchiveURL: URL = sharedContainerDirectory.appendingPathComponent("whateverYouNeed")

NSKeyedArchiver.archiveRootObject(yourObject, toFile: sharedArchiveURL.path)

对于核心数据

您可以如下设置容器。我已经从this answer那里获得了这段代码,因为我自己实际上还没有尝试使用Core Data。

您使用containerURL(forSecurityApplicationGroupIdentifier: "group.appDomain.appName")!在共享容器中完成这项工作。

lazy var persistentContainer: NSPersistentContainer = {
    /*
    The persistent container for the application.
    This implementation creates and returns a container, having loaded 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.
     */
    let container = NSPersistentContainer(name: "xx")

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

    let storeUrl =  FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.appDomain.appName")!.appendingPathComponent("xx.sqlite")

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

    container.persistentStoreDescriptions = [NSPersistentStoreDescription(url:  FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.xxx.xx.container")!.appendingPathComponent("xx.sqlite"))]

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

This answer提供了一种迁移持久性存储的方法。

正如我所提到的,我对Ionic并不熟悉,所以我不确定在这种情况下如何工作会改变这种技术。

我希望这会有所帮助。

答案 1 :(得分:1)

我本来应该发表评论,但我无法这样做。

我能够看到,在加载本机iOS应用程序之后,一个Ionic项目的捆绑结构与Library / Application Support / DisplayName.sqlite中的数据仍然存在并且数据库中的数据仍然完好无损。 (注意:这是通过Xcode而不是通过App Store进行部署)

您可以使用Xcode->窗口->设备和模拟器->设备选项卡->单击您的应用程序->设置齿轮->下载容器->保存显示包内容后

由于某种原因,我无法使用Ionic SQLite本机插件打开数据库。那是我所能得到的。我认为这可能与Application Support文件夹的空间有关。

答案 2 :(得分:1)

您可以在不使用AirDrop或“自定义网址”的情况下进行转换。这个想法基于离子的工作原理。大部分离子功能取决于社区开发的插件,例如使用硬件功能。

使用特定于设备的功能来完成本机代码,然后创建JS包装器类,以在您的代码和本机代码之间建立桥梁。

我建议您编写本机代码,该代码将访问CoreData中的数据和文件,然后使用cordova插件技术在本机代码和离子代码之间建立通信。这是关于Creating Custom Plugin for ionicsample github project

的精彩文章