我有一个使用今日小部件的应用。它通过使用组共享数据。它当前正在窗口小部件中正确显示数据。如果我更改应用程序上的数据然后显示小部件,它会正确更新。现在,我想更新小部件上的一些数据并将其反映在应用程序上。
该应用上有UITableView
,因此我使用NSFetchedResultsController
来获取表格中的数据。窗口小部件在fetchedResultsController中的项之间滚动,并显示数据。在小部件上可以更新任意数量的项目。
我知道这可以做到,因为我已经看到它在其他应用上完成了。当我更新小部件上的数据时,我无法弄清楚如何让应用知道,以便可以刷新它。
关于我的尝试,并不多,因为我想不出要尝试什么。我添加了这个:
func controllerDidChangeContent(controller: NSFetchedResultsController) {
print ("Controller changed")
}
当我更改应用程序上的数据时会触发此事件,但在更改窗口小部件中的数据时不会触发此事件。
根据下面的建议,我在app上添加了以下代码到viewDidLoad:
let center = NSNotificationCenter.defaultCenter()
center.addObserver(self, selector: #selector(self.contextUpdated(_:)),name: NSManagedObjectContextDidSaveNotification,
object: context)
然后抓住通知:
@IBAction func contextUpdated(notification: NSNotification) {
print("Notification recieved")
}
我得到的结果与我对controllerDidChangeContent事件的结果相同 - 它在对应用程序上的数据进行更改时触发,但我从小部件中得不到任何结果。我的理解是小部件和应用程序不在同一容器中,这就是我没有收到通知的原因。
我注意到的另一件事是,一旦我在小部件上保存数据,应用程序上的moc就不再允许我使用它来保存数据。也许是因为小部件上下文更新了数据并使应用程序上下文无效?
答案 0 :(得分:0)
NSFetchedResultsController
应自动更新。但是,您还可以在为特定实体和属性等保存moc时订阅更改。下面的示例代码可帮助您入门。订阅更改后,您可以过滤掉更改的内容,提取对象,然后相应地更新表格。
let center = NotificationCenter.default
center.addObserver(self,
selector: #selector(CLASS_NAME_HERE.contextUpdated(_:)),
name: NSNotification.Name.NSManagedObjectContextDidSave,
object: context)
// we would like to get notified for all changes to the given entity
// if you need more specific data, update the predicate as needed
let entityPredicate = NSPredicate(format: "entity.name == %@", ENTITIY_NAME_HERE)
func contextUpdated(_ notification: Notification) {
// all changes (inserted, updated, deleted) to the moc matching the predicate are inside notification
print("\(notification)
}
您可以按如下方式过滤通知。下面是插入的,但也可以轻松修改以获取更新和删除的对象。
let info = (notification as NSNotification).userInfo
if let set = info?[NSInsertedObjectsKey] as? NSSet, let insert = set.allObjects as? [NSManagedObject] {
let inserted = insert.filter { return predicate.evaluate(with: $0) }
}