mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-11 20:00:30 +01:00
CoreStore with differenceKit #241
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 @eraydiler on GitHub (Nov 16, 2018).
Hello,
I'm trying to use DifferenceKit library for updating UI triggered by relevant CoreStore methods.
I simply need to have two different collection (before-update, after-update) to use these library.
However, it looks like the
dataProvider.objects, which holds elements represented in UI, is being automatically updated, so I am unable to make a comparison between previous and updated data.Is there a way to access the previous state of these objects so that I can make a comparison with the updated objects?
@JohnEstropia commented on GitHub (Nov 19, 2018):
ListMonitor(or strictly speaking,NSFetchedResultsController) manages these changes for you so they are not really a good fit for DifferenceKit. If you run DifferenceKit on top ofListMonitors you will be unnecessarily duplicating a lot of heavy work.Diff'ing libraries like
DifferenceKitwere designed for objects that don't manage states, meaning you have an "old version" and a "new version". With ORMs like Core Data, objects are live and update themselves in real time.@tosbaha commented on GitHub (Nov 22, 2018):
I have coded something before maybe it can help you too. If you are downloading data from a web server and want to compare the values, you may use a DifferenceKit. I personally use
DeepDiffSo let's say you have new Data coming from a web server Which is called
Postand eachPosthave somePostDetail1:M RelationshipIn order for this code to work, your NSManagedObject classes must conform to
ImportableObjectprotocol.@JohnEstropia commented on GitHub (Dec 5, 2018):
@tosbaha I may be missing something your implementation, but will
.replacebe called if there are just updates to thePostDetail? The way I see it is by the time you callPosDetail.init, thedetailinstance would be the updated instance. (Unless you are managing the update order as well)Also, since you are doing this in the context of the transaction, you would need extra handling if there was an error further on.
@tosbaha commented on GitHub (Dec 5, 2018):
I haven't tested all possible cases but here is how it works.
DeepDiffcompares both Post and arrayPostDetailaccording toDeepDiffreport it either deletes,insert or replace the item from the array. So ifPostDetailarray has 100 items and only one is added later on, I only insert once.Likewise, if 99 details are same but last detail is changed, I only replace the last item. Therefore I prevent heavy delete insert operations. As I said, I could be missing something but so far it works faster then deleting/replacing all details when the data on server changes. I will appreciate if you tell me if there is any mistake in my logic or implementation. Thanks.@tosbaha commented on GitHub (Dec 16, 2018):
I spoke too soon :( My code only works if last detail is changed since my insert code is buggy. It is not possible to insert at given index.
Above code doesn't seem to have any effect. It always inserts at the last when I use
try transaction.importObjectHow can I solve this issue?
Only hacky way I have found is this
Since object is inserted at the end of Array, I move the object from end to whatever the index it is.
self.detail.moveObjects(at: IndexSet(integer: self.detail.count - 1 ), to: index)@JohnEstropia commented on GitHub (Dec 18, 2018):
Assuming
self.detailis a to-many relationship, andPostCDanNSManagedObjectsubclass, you cannot directly mutate theNSOrderedSetorNSSetproperty. See https://stackoverflow.com/a/27888302/809614My suggestion for your case (if I understood the intent correctly):
var oldArray: [PostDetail]from your existing message objects before you do any importsdiff(old: oldArray, new: source.details)(still before importing)self.detailsinto a temporaryvar temp: [PostDetailCD] = []changesand work with thetemparray, notself.detailsself.details = NSOrderedSet(array: temp)It is a lot faster to set a relationship all at once than mutating the internal collection for each iteration.
@JohnEstropia commented on GitHub (Dec 18, 2018):
Just a note here, that @eraydiler and @tosbaha 's cases are totally different.
@eraydiler is trying to use Core Data objects directly with within
diff(), while @tosbaha 's is diff'ing only theImportSourcearrays. The latter may be necessary depending on the use case, but the former is something I would discourage.@tosbaha commented on GitHub (Dec 18, 2018):
Thanks a lot @JohnEstropia I decided to just check if there is difference or not. If different set all at once. Thanks once again for taking your time for explaining in detail.
@eraydiler commented on GitHub (Dec 21, 2018):
Thanks for the answers @JohnEstropia, @tosbaha. After having some time I decided to go without using differenceKit.
@JohnEstropia commented on GitHub (Jan 8, 2020):
This is quite old but to anyone following the thread, CoreStore now has
ListPublishers which work in tandem withDiffableDataSources. This uses the same algorithm that DifferenceKit uses, so check the README for more info. Closing this thread now