I have the following case, I get data when loading the application, it is an array of ChatUserPersonalConversationModel
models, I store this array in Realm as a separate model. What is the best way to do the following when I get an array and if the previous model is not contained in the resulting array, then I delete it from Realm.
I wrote the following code, it works for me, but I think that it can do better.
func updateChatUserPersonalConversationModels(_ chatUserPersonalConversationModels: [ChatUserPersonalConversationModel]) {
DispatchQueue.main.async {
do {
let realm = try Realm()
let existChatUserPersonalConversationModels = realm.objects(ChatUserPersonalConversationModel.self)
for existChatUserPersonalConversationModel in existChatUserPersonalConversationModels {
if !chatUserPersonalConversationModels.contains(where: { (newChatUserPersonalConversationModel) -> Bool in
return newChatUserPersonalConversationModel.id == existChatUserPersonalConversationModel.id
}) {
try realm.write {
realm.delete(existChatUserPersonalConversationModel)
}
}
}
try realm.write {
realm.add(chatUserPersonalConversationModels, update: true)
}
} catch {
debugPrint(error.localizedDescription)
}
}
}
Realm doesn't have any built-in functionality to achieve what you want. An alternative to what you have is to leverage Swift's Set
type.
First, you should make sure equality and the hash value property are defined for your model class, and you should probably have a primary key (which seems to be id
).
Next, turn your arrays of existing and new models into Set
s. Set
has an initializer that takes any sequence of objects, so you can pass arrays and Realm List
s alike into it.
Next, use the subtract(_:)
method on Set
to get a new set containing just the elements you want to delete:
// itemsToDelete contains models in oldModels that aren't in newModels
let itemsToDelete = oldModels.subtract(newModels)
Finally, you can use the Realm delete(_:)
method that takes a sequence to delete all the obsolete models at once:
try! realm.write {
realm.delete(itemsToDelete)
}
I hope this helps. Note that this isn't a panacea; if your arrays are huge you may want to consider whether this approach uses too much memory.