Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save teologov/8af7b71ecfdee60033e0fd8659930c43 to your computer and use it in GitHub Desktop.
Save teologov/8af7b71ecfdee60033e0fd8659930c43 to your computer and use it in GitHub Desktop.
Cascade deletion for RealmSwift
import RealmSwift
import Realm
protocol CascadeDeleting: class {
func delete<Entity>(_ list: List<Entity>, cascading: Bool)
func delete<Entity>(_ results: Results<Entity>, cascading: Bool)
func delete<Entity: Object>(_ entity: Entity, cascading: Bool)
}
extension Realm: CascadeDeleting {
func delete<Entity>(_ list: List<Entity>, cascading: Bool) {
list.forEach {
delete($0, cascading: cascading)
}
}
func delete<Entity>(_ results: Results<Entity>, cascading: Bool) {
results.forEach {
delete($0, cascading: cascading)
}
}
func delete<Entity: Object>(_ entity: Entity, cascading: Bool) {
if cascading {
cascadeDelete(entity)
} else {
delete(entity)
}
}
}
private extension Realm {
private func cascadeDelete(_ entity: RLMObjectBase) {
guard let entity = entity as? Object else { return }
var toBeDeleted = Set<RLMObjectBase>()
toBeDeleted.insert(entity)
while !toBeDeleted.isEmpty {
guard let element = toBeDeleted.removeFirst() as? Object,
!element.isInvalidated else { continue }
resolve(element: element, toBeDeleted: &toBeDeleted)
}
}
private func resolve(element: Object, toBeDeleted: inout Set<RLMObjectBase>) {
element.objectSchema.properties.forEach {
guard let value = element.value(forKey: $0.name) else { return }
if let entity = value as? RLMObjectBase {
toBeDeleted.insert(entity)
} else if let list = value as? RealmSwift.ListBase {
for index in 0..<list._rlmArray.count {
toBeDeleted.insert(list._rlmArray.object(at: index))
}
}
}
delete(element)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment