我目前在Apple的App Store中有一个Swift iOS应用。我有很多用户,我想制作一个新版本,并帮助当前用户迁移到新版本。仅供参考:新版本是Ionic应用程序。
从数据角度看,我的应用程序使用的是Core Data,而没有任何iCloud或同步支持。它包含JSON数据以及多个图像。因此,我需要捆绑当前数据,并找到一种将其引入新的ionic应用程序版本的方法。
基本上我的问题是:是否可以在应用程序的documents目录中进行写入,并让新版本抓取该文件以导入其数据?是否可以让两个应用程序传输除AirDrop或自定义URL之外的其他数据?
我不想远程上传数据,我想在设备上本地且无缝地完成所有操作,因此用户不必手动执行任何操作。
欢迎提出建议,谢谢!
答案 0 :(得分:2)
我建议使用应用程序组来获取共享容器。我对Ionic不熟悉,但这在本机Swift中非常简单。它允许多个应用或扩展程序访问共享的数据容器,如下图所示:
(来自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 ionic和sample github project
的精彩文章