iPhone 和 Apple Watch 应用程序之间 Core Data SQLite 存储更改的通知
Notification of changes in Core Data SQLite store between iPhone and Apple Watch app
我有一个 iPhone (iOS 8) 和 Apple Watch (watchOS 1) 应用程序,它们使用 Core Data(SQLite 商店,位于共享应用程序组中)共享数据。这两个应用程序都使用放置在共享框架中的相同数据访问代码。 NSPersistentStoreCoordinator
正在按以下方式设置:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
let sharedContainerURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(self.sharedAppGroup)!
let storeURL = sharedContainerURL.URLByAppendingPathComponent(self.databaseName)
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
var error: NSError? = nil
if coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) == nil {
fatalError("Unable to add persistent store: \(error)")
}
return coordinator
}()
根据我的理解,在运行时每个应用程序都有自己的 NSPersistenStoreCoordinator
实例(因为 iPhone 应用程序和 WatchKit 扩展确实有完全独立的地址 space),但是这两个连接到完全相同的 SQLite 数据库文件。
当 Watch 应用更改公共 SQLite 存储中的某些数据时如何通知 iPhone 应用,反之亦然:当 iPhone 应用更改某些数据时如何通知 Watch 应用公共持久存储中的数据?
不容易。无法在两个应用程序之间发送直接通信。
我目前在这方面的建议是使用磁盘上的文件,其中包含从一个应用程序更改到另一个应用程序的任何内容的 objectID。
当您检测到磁盘保存时,您会写入一个文件,例如 JSON 并且最多包含三个数组:更新、插入、删除。文件名应该是某种形式的时间戳。
另外,您应该监视目录中是否有其他应用程序创建的任何文件并使用它们。加载 ObjectID,然后从 ala iCloud 或 iOS 9 中创建一个远程通知。然后在处理后删除文件。
启动时,从其他商店中删除所有文件,因为您会自动知道启动前发生的任何事情。
不简单但相当直接。
我发现非常满意的解决方案是使用 MMWormhole 库。
它通过使用共享应用程序组中的 CFNotificationCenter Darwin 通知和 writing/reading 数据文件来工作,这导致 iOS 应用程序和应用程序扩展(Watch 应用程序,今天的小部件,等)。
基本代码如下:
虫洞初始化
wormhole = MMWormhole(applicationGroupIdentifier: appGroup, optionalDirectory: nil)
将数据对象传递到虫洞
let payload = ["Key": "Value"]
wormhole.passMessageObject(payload, identifier: theSameMessageIdentifier)
侦听来自虫洞的传入对象
wormhole.listenForMessageWithIdentifier(theSameMessageIdentifier) { message -> Void in
if let payloadDictionary = message as? Dictionary<String, String> {
// Do some work
}
}
就这么简单。
我有一个 iPhone (iOS 8) 和 Apple Watch (watchOS 1) 应用程序,它们使用 Core Data(SQLite 商店,位于共享应用程序组中)共享数据。这两个应用程序都使用放置在共享框架中的相同数据访问代码。 NSPersistentStoreCoordinator
正在按以下方式设置:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
let sharedContainerURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(self.sharedAppGroup)!
let storeURL = sharedContainerURL.URLByAppendingPathComponent(self.databaseName)
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
var error: NSError? = nil
if coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) == nil {
fatalError("Unable to add persistent store: \(error)")
}
return coordinator
}()
根据我的理解,在运行时每个应用程序都有自己的 NSPersistenStoreCoordinator
实例(因为 iPhone 应用程序和 WatchKit 扩展确实有完全独立的地址 space),但是这两个连接到完全相同的 SQLite 数据库文件。
当 Watch 应用更改公共 SQLite 存储中的某些数据时如何通知 iPhone 应用,反之亦然:当 iPhone 应用更改某些数据时如何通知 Watch 应用公共持久存储中的数据?
不容易。无法在两个应用程序之间发送直接通信。
我目前在这方面的建议是使用磁盘上的文件,其中包含从一个应用程序更改到另一个应用程序的任何内容的 objectID。
当您检测到磁盘保存时,您会写入一个文件,例如 JSON 并且最多包含三个数组:更新、插入、删除。文件名应该是某种形式的时间戳。
另外,您应该监视目录中是否有其他应用程序创建的任何文件并使用它们。加载 ObjectID,然后从 ala iCloud 或 iOS 9 中创建一个远程通知。然后在处理后删除文件。
启动时,从其他商店中删除所有文件,因为您会自动知道启动前发生的任何事情。
不简单但相当直接。
我发现非常满意的解决方案是使用 MMWormhole 库。
它通过使用共享应用程序组中的 CFNotificationCenter Darwin 通知和 writing/reading 数据文件来工作,这导致 iOS 应用程序和应用程序扩展(Watch 应用程序,今天的小部件,等)。
基本代码如下:
虫洞初始化
wormhole = MMWormhole(applicationGroupIdentifier: appGroup, optionalDirectory: nil)
将数据对象传递到虫洞
let payload = ["Key": "Value"] wormhole.passMessageObject(payload, identifier: theSameMessageIdentifier)
侦听来自虫洞的传入对象
wormhole.listenForMessageWithIdentifier(theSameMessageIdentifier) { message -> Void in if let payloadDictionary = message as? Dictionary<String, String> { // Do some work } }
就这么简单。