README and documentationIGListKit version: 3.4.0I have a ViewController listing all the users from an array of user objects. After selecting one user I want to reload the perticular section.
func didSelectAtIndex(_ index: Int) {
let user = users[index]
user.name = "User " + "\(index) updated"
adapter.performUpdates(animated: true, completion: nil)
}
class UserInfo: ListDiffable {
var id: Int!
var name: String!
init(id: Int, name: String) {
self.id = id
self.name = name
}
func diffIdentifier() -> NSObjectProtocol {
return id as NSObjectProtocol
}
func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
guard let object = object as? UserInfo else {
return true
}
*both the objects are same, I know I just updated the same object.*
print("self.name = \(self.name)")
print("object.name = \(object.name)")
return self.name == object.name
}
}
Is this an expected behaviour? I know I can reload the SectionController from the same controller using
performBatch like this.
collectionContext?.performBatch(animated: true, updates: { (batchContext) in
object.isSelected = !object.isSelected
batchContext.reload(self)
})
Then what is the use of func isEqual(toDiffableObject object: ListDiffable?) -> Bool ?
You need to use immutable objects. Aka create new users, instead of mutating the existing ones.
Immutability
The data should be immutable. If you return mutable objects that you will be editing later, IGListKit will not be able to diff the models accurately. This is because the instances have already been changed. Thus, the updates to the objects would be lost. Instead, always return a newly instantiated, immutable object and implement IGListDiffable.
From the docs here: https://instagram.github.io/IGListKit/getting-started.html
Closing as that's exactly the issue. Mutating the instance will just change the instance to itself. You need to create a new object.
@calimarkus @rnystrom Thanks. Yes! I am doing the same. Creating new instances of UserViewModel in "func objects(for listAdapter: ListAdapter) -> [ListDiffable] {}" and returning from there.
In your example above you mutate an existing model:
func didSelectAtIndex(_ index: Int) {
let user = users[index]
user.name = "User " + "\(index) updated"
adapter.performUpdates(animated: true, completion: nil)
}
You want to avoid that and instead create new models. Your .name property is not immutable.
I'm creating brand new objects, and I can confirm that through their memory address, however, isEqual to when performing updates, always compares the new object, not the new object with the old one
Most helpful comment
You need to use immutable objects. Aka create new users, instead of mutating the existing ones.
From the docs here: https://instagram.github.io/IGListKit/getting-started.html