简体   繁体   English

今日扩展更改后在应用上刷新CoreData

[英]Refresh CoreData on app after change on Today Extension

I have an app that is using a today widget. 我有一个正在使用Today小部件的应用程序。 It has shared data by using a group. 它通过使用组共享了数据。 It is currently displaying data correctly in the widget. 当前它在小部件中正确显示数据。 If I change the data on the app and then show the widget, it updates correctly. 如果我更改了应用程序上的数据,然后显示了小部件,则它将正确更新。 Now, I want to update some of the data on the widget and have it reflect on the app. 现在,我想更新小部件上的某些数据,并将其反映在应用程序上。

The app has a UITableView on it, so I am using NSFetchedResultsController to get the data in the table. 该应用程序具有UITableView ,因此我正在使用NSFetchedResultsController来获取表中的数据。 The widget scrolls between items in the fetchedResultsController, and displays the data. 小部件在fetchedResultsController中的项目之间滚动,并显示数据。 It's possible to update any number of items while on the widget. 可以在窗口小部件上更新任何数量的项目。

I know that this can be done, because I've seen it done on other apps. 我知道可以这样做,因为我已经在其他应用程序上看到了。 I just can't work out how to make the app know when I've updated data on the widget, so that it can be refreshed. 我只是想不出如何在小部件上更新数据后使应用程序知道,以便可以刷新它。

As to what I've tried, not much because I couldn't think of what to try. 至于我尝试过的东西,不是很多,因为我想不出要尝试什么。 I did add this: 我确实添加了这个:

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    print ("Controller changed")
}

This event fires when I change the data on the app, but does not fire when changing the data from the widget. 当我更改应用程序上的数据时,将触发此事件,但从窗口小部件中更改数据时,则不会触发。

Per the suggestion below, I added the following code to viewDidLoad on the app: 根据以下建议,我在应用程序的viewDidLoad中添加了以下代码:

    let center = NSNotificationCenter.defaultCenter()

    center.addObserver(self, selector: #selector(self.contextUpdated(_:)),name: NSManagedObjectContextDidSaveNotification,
    object: context)

And then to catch the notification: 然后捕获通知:

@IBAction func contextUpdated(notification: NSNotification) {
    print("Notification recieved")
}

I had the same results as I did with the controllerDidChangeContent event - it fired when making a change to the data on the app, but I got nothing from the widget. 我得到的结果与controllerDidChangeContent事件的结果相同-更改应用程序上的数据时会触发该事件,但是小部件没有任何作用。 My understanding is that the widget and the app are not in the same container, and that's why I'm not receiving the notification. 我的理解是,小部件和应用程序不在同一个容器中,这就是为什么我没有收到通知的原因。

Another thing I've noticed is that once I've saved data on the widget, the moc on the app no longer lets me save data using it. 我注意到的另一件事是,一旦我在小部件上保存了数据,应用程序上的Moc就不再允许我使用它来保存数据。 Perhaps because the context on the widget updated the data and invalidated the context on the app? 也许是因为小部件上的上下文更新了数据并使应用程序上的上下文无效?

NSFetchedResultsController should get updated automatically once you save the moc. 保存NSFetchedResultsController应该会自动更新。 However, you can also subscribe to changes when the moc gets saved for specific entities and properties etc. Example code is below to get you started. 但是,当为特定实体和属性等保存moc时,您也可以订阅更改。下面的示例代码可帮助您入门。 Once you subscribe to the changes, you can filter out what changed, extract the objects then update your table accordingly. 订阅更改后,您可以过滤出更改内容,提取对象,然后相应地更新表。

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

You can filter the notification as follows. 您可以按以下方式过滤通知。 Below is for inserted, but can easily be modified to get updated and deleted objects as well. 以下是用于插入的对象,但可以轻松进行修改以获取更新和删除的对象。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM