I have a few realm managed objects in my app that need to keep a track of the timestamp it was last modified.
I could implement the repository programming pattern for this, or I could just remember to set the property every time I change something on those objects (which is a fallback idea, as horrible as it sounds).
What I've done is create a singleton object that monitors collections of objects that I want to keep a "last modified" timestamp for. This is booted up on app start and keep's an eye on the collections for any modifications.
The general "flow" is:
- Wait for change notification
- On change, loop the modified indexes
- Check the index exists before trying to access the object (just in case)
realm.writea new last modified Date to the object
As you can probably guess already (and as I suspected), that realm.write to update my last modified timestamp, then creates a new change notification, which in turn makes the timestamp update again. So it ends up just looping forever after the first change.
Looking for options on how best to solve this.
Here's what I have implemented:
class RealmCollectionLastModifiedMonitor {
static let shared = RealmCollectionLastModifiedMonitor()
private var formObjectNotificationToken: NotificationToken?
private init() {
startMonitoring()
}
deinit {
stopMonitoring()
}
func startMonitoring() {
let realm = try! Realm()
let caseforms = realm.objects(CaseForm.self)
formObjectNotificationToken = caseforms.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
switch changes {
case .initial:
// Do nothing for now - as i've not worked out what this is :P
break
case .update(_, let deletions, let insertions, let modifications):
// Some debug output
print("Form collection change: Deletions = \(deletions.count), Insertions = \(insertions.count), Modifications = \(modifications.count)")
// Loop the modificated indexes, get a reference to the form, then update the last modified timestamp
for i in modifications {
if caseforms.indices.contains(i) {
do {
try realm.write {
caseforms[i].lastModified = Date()
}
} catch {
print("Failed to update modified date")
}
}
}
break
case .error(let error):
// Do nothing for now - If a write fails, we could rollback, but it's not uber-important
break
}
}
}
func stopMonitoring() {
formObjectNotificationToken = nil
}
}