mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-11 20:00:30 +01:00
Changes by mergeChanges(fromContextDidSave:) go unnoticed in ListMonitor #135
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @manmal on GitHub (Apr 16, 2017).
Hi @JohnEstropia,
First of all, thank you for the great work. CoreData is a beast that needs to be kept in a cage, and CoreStore is a very fine cage :) Alas, I know what I'm talking about. I have sworn to myself to never use CoreData without an idiomatic wrapper again.
I'm currently trying to integrate CoreStore with Ensembles (ensembles.io), which syncs the database with various data sources. The way I would approach this integration is to take the Did-Save-Notification that Ensembles emits and merge it like so:
That works, insofar as the
internalContextthen has all the objects inregisteredObjects. However, this does not cause updates to be processed by myListMonitor, and thus the changes do not show up in my UITableView. Restarting the app DOES show the new entries in the table, so the inserts to the DB actually worked (Ensembles writes directly to the store, so that's no surprise; the notification is only a way to integrate changes into the UI-bound contexts).A potential solution is provided here: http://stackoverflow.com/a/16296365/458603
The idea is to refresh the updated/inserted/deleted objects in the main context such that the changes get noticed by the assigned fetch request.
But I thought, maybe there is a cleaner, more CoreStore-idiomatic way of doing this. It would be really nice to animate the changes, so calling
refetchon theListMonitoris only my fallback option.@JohnEstropia commented on GitHub (Apr 16, 2017):
Although I'm not sure if this would work correctly, I think you're on the right track.
I do have some concerns though, is the store (sqlite file) used by Ensembles the same store used by the CoreStore stack?
@manmal commented on GitHub (Apr 16, 2017):
@JohnEstropia Ok, I'll try that and keep you posted.
Definitely, yes, the same .momd and the same sqlite File. Not sure whether it would work with a separate database. The great thing about Ensembles is btw that it does not complete a merge if the mainContext has been saved to since the sync started. In that case, the sync has to be restarted. I have to investigate what would happen if I have unsaved changes in the mainContext and merge changes. Probably the changes from the Did-Save-Notification would win.
@manmal commented on GitHub (Apr 16, 2017):
This seems to work fine: https://gist.github.com/manmal/1702221a478978668bd9e3fed5e2653e
I'll update the gist in case it needs further changes (should be in production til end of June).
@JohnEstropia commented on GitHub (Apr 16, 2017):
@manmal Oh, glad you solved that by yourself :P
Just for reference, CoreStore does the same workaround here:
c0d72799b4/Sources/Internal/NSManagedObjectContext%2BSetup.swift (L118)Just a heads up though, I think it is ironically safer to use unsafe transactions instead (
CoreStore.beginUnsafe()). CoreStore's root context need to merge Ensemble's changes as soon as possible, and asynchronous and synchronous transactions will unnecessarily delay that merge due to their queueing mechanism.@manmal commented on GitHub (Apr 16, 2017):
@JohnEstropia Yes, the first heads-up you gave me was already very helpful :)
But given the scenario that all objects are already known by the main context, would it not be better (smoother UI) if those were inserted on the background thread? Or does this not really matter because the eventual background-to-main-merging would do the very same insertions/updates on the main thread anyway?
@JohnEstropia commented on GitHub (Apr 16, 2017):
CoreStore is not designed to accept changes from the main context. All transactions in CoreStore (including unsafe transactions) are background contexts.
@manmal commented on GitHub (Apr 16, 2017):
Ok great! I updated my code with
beginUnsafe- it's all-main-thread now.https://gist.github.com/manmal/1702221a478978668bd9e3fed5e2653e