I have a simple ticked off list in Realm, where I am using NotificationToken
to check for updates in the datasource and hereafter updates the tableView with the following items:
class Item : Object {
dynamic var name = ""
dynamic var isTickedOff = false
dynamic var timeStamp : Date?
}
The model:
var items: Results<Item> {
get {
let results = self.realm.objects(Item.self)
let alphabetic = SortDescriptor(property: "name", ascending: true)
let tickedOff = SortDescriptor(property: "isTickedOff", ascending: true)
let timestamp = SortDescriptor(property: "timeStamp", ascending: false)
return results.sorted(by: [tickedOff, timestamp, alphabetic]).filter("isTickedOff = %@ || isTickedOff = %@", false, self.includeAll)
}
}
I have a switch in my tableview, where the user can change the self.includeAll
property.
When inserting, deleting items or selecting them (resulting in setting them to isTickedOff
or !isTickedOff
) triggers the notification and updates the tableView. However, changing the self.includeAll
property does not trigger the notification even though the items
property is modified. I could include self.tableView.reloadData()
when the user triggers the switch, but I would like the more smooth animations through the notification.
Is it me, who understands notifications wrong or is it a bug?
Thanks in advance!
Realm doesn't observe external properties, so it can't know when a property that is being used in a predicate query has changed, and to then subsequently generate a change notification off that.
When you access items
the next time, that will give it a sufficient event to recalculate the contents, but by that point, it won't trigger a notification.
Obviously, like you said, the easiest solution would be to simply call tableView.reloadData()
since that will force a refetch on items
but there'll be no animation. Or conversely, like this SO question says, you can call tableView.reloadSections
to actually enable a 're-shuffling' animation.
Finally, it might be a rather dirty hack, but if you still want it to trigger a Realm-based change notification, you could potentially just open a Realm write notification, change the includeAll
property, and then close the write transaction to try and 'trick' Realm into performing an update.
One final point of note. I might not have enough information on this, so this might be incorrect, but if you're registering a Realm notification block off the items
property, be aware that the way you've implemented that getter means that a new object is generated each time you call it. It might be more appropriate to mark that property as lazy
so it's saved after the first call.