IGListKit: [Core Data] adapter.performUpdates does not trigger any diffing on NSManagedObjects
Hello,
I have a question about the framework, because from the doc I would expect a behaviour, but it does not happen. I cannot provide a example project, because my app is huge and uses CoreData etc… and it would take me a lot of time to set it up.
The idea is the following:
- I display CoreData object with IGListKit based on a timestamp
- CoreData objects are updated with background network requests
- The AdapterDataSource is using a NSFetchedResultController to monitor for object changes
- When the NSFetchedResultControllerDelegate is informed of CoreData changes it calls: adapter.performUpdates
What happens is:
- Datasource method objects(for listAdapter) is called again, the objects obtain the new correct order
- UI is animated and sections shuffle around in the right order
however:
- IGListDiffable Objects isEqual() method is never called
- Section Controller are not reloaded
I would expect that calling performUpdates:
- 🆗 the datasource refreshes list of object
- 🆗 the UI is animated
- ⚠️ the objects are checked to see if they have changed
- ⚠️ the content of the section controller is recalculated if needed
- ⚠️ UI content is updated correcly
I could call reloadData but I would lose the animation, and the purpose of using the framework.
There is something I understood wrong, or that I am not doing?
You can reproduce this in @rnystrom sample for RayWendlich: https://koenig-media.raywenderlich.com/uploads/2016/12/MarsLink_Final.zip
I put the code here: https://github.com/racer1988/IGListKitPerformUpdates
EDIT:
Using a IGListReloadDataUpdater instead of a IGListAdapterUpdater provides the expected result, without animation and losing the scroll position (due to reload data)
I hence believe there is a bug (?) in the IGListAdapterUpdater that do not take in account model changes but just inserts and delete. Is this the expected behaviour?
Do I need to write my own adapter to manage the changes to the datamodel?
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 16 (8 by maintainers)
Yep, I’ll draft something next week, so I can open a PR and we can contribute to it
I manage to make the update work on the example project, by implementing a specific diffIdentifier and isEqual method for the model and adding the copying mechanism on the datasource.
I guess that it would be nice to add in the IGListKit documentation that the framework is working out of the box only for immutable datamodels that are recalculated every time there is a perform updates.
Else if the model is mutable or it is not recalculated, it is necessary to implement NSCopying a create a copy of it in the datasource, in order to get the updates in UI.
This is not clear imho in the getting started guide and could bring to misleading development
We’ll try to implement a better diffing on our side to see if that solves the issue with ViewModel. If that works, I’ll work on the FAQ for CoreData with ViewModel
@racer1988
You bet! That’s where I was leading 😄 It would be really really helpful. If you’re feeling good should we close this?
@jessesquires’s idea sounds awesome. Let us know if this works out! Might be a worthy example project too?
😅
@rnystrom @jessesquires thank you for your answers, now the whole thing and what is supposed to happen makes perfect sense.
I added a bit of code examples in #461.
I will implement this in my work project, not sure if with ViewModel approach or by passing around NSManagedObjectID (which is also a good idea for a architecture that supports well CoreData multithreading @jessesquires 😉. Sometimes it is easy to forget not to pass a coredata object around, and end up with changing thread in the subsequent classes)
I will probably write a repository with examples and “tutorial” for IGListKit later on. Maybe it can be used/merged into IGListKit FAQ #405 or into the documentation later on?