Filter store transactions for changes relevant to the current view.
Use persistent history tracking to determine what changes have occurred in the store, and to update your view context only as needed.
For example, consider an app that sometimes shows a list of colors, and sometimes shows a list of shapes. As the user views the Color objects from the view context, a background context may download additional Color data from a remote source. If the import happens through a batch operation, the save to the store doesn’t generate an NSManagedObjectContextDidSave notification, and the view misses these relevant updates. Alternatively, the background context may save changes to the store that don’t affect the current view—for example, inserting, modifying, or deleting Shape objects. These changes do generate context save events, so your view context processes them even though it doesn’t need to.
Persistent history solves the problem by keeping track of every transaction on the store. You can filter this history for relevant changes and decide how or whether to update a view.
Set a unique name for each context you create, to record a contextName in each relevant transaction.
Additionally, set the context’s transactionAuthor at the time of use to differentiate among multiple call sites that modify a single context. Doing this records an author in the subsequent transactions.
Reset the author to nil after the transaction to prevent misattribution of future transactions.
Keep Track of Your Place in the History
Create an instance of NSPersistentHistoryToken to keep track of the most recent history that you have processed.
You can encode the token to disk so that when your app exits, you can keep track of where you were in the history. When you relaunch your app, fetch history based on your token.
Alternatively you can use fetchHistory(after:) to get history after a particular date, or after a particular a transaction.
Read History Transactions
Each transaction represents a set of changes. Iterate through the array of transactions to learn their details. The following code loops through the results of the fetchHistoryRequest to inspect the properties of each transaction.
A transaction’s changes array includes information about multiple changes. A single NSPersistentHistoryChange represents the insertion, update, or deletion of an object.
Iterate through a transaction’s changes to identify each object that changed, the type of change that occurred, and any details about the change.
In the case of an update, the updatedProperties set includes any updated attributes and relationships. In the case of a deletion, the tombstone dictionary includes key-value pairs for any attributes marked for preservation after deletion.
Filter for Transactions Relevant to the View
Filter the history to narrow it to changes affecting the current view. The following code filters for changes to Color instances, updating the last transaction token as it goes.
Relevant changes may include all changes to a given entity, or more selectively, only changes to those properties that are visible on the screen.
Because persistent history tracking transactions take up space on disk, determine a clean-up strategy to remove them when they are no longer needed. Before pruning history, a single gatekeeper should ensure that your app and its clients have consumed the history they need.
Similar to fetching history, you can use deleteHistory(before:) to delete history older than a token, a transaction, or a date. For example, you can delete all transactions older than seven days.
If you attempt to fetch purged history, Core Data throws an expired token error.