Skip to content

Instantly share code, notes, and snippets.

@ebubekirsezer
Created October 22, 2022 09:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ebubekirsezer/cf7dea0dae7462bb1cec3a536f4d24aa to your computer and use it in GitHub Desktop.
Save ebubekirsezer/cf7dea0dae7462bb1cec3a536f4d24aa to your computer and use it in GitHub Desktop.
//
// RealmCascadeDeletion.swift
// GitStar
//
// Created by EbubekirSezer on 21.10.2022.
//
import Foundation
import RealmSwift
import Realm
protocol CascadeDeleting {
func delete<S: Sequence>(_ objects: S, cascading: Bool) where S.Iterator.Element: Object
func delete<Entity: Object>(_ entity: Entity, cascading: Bool)
}
extension Realm: CascadeDeleting {
func delete<S: Sequence>(_ objects: S, cascading: Bool) where S.Iterator.Element: Object {
for obj in objects {
delete(obj, 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? RLMSwiftCollectionBase {
for index in 0..<list._rlmCollection.count {
if let entity = list._rlmCollection.object(at: index) as? RLMObjectBase {
toBeDeleted.insert(entity)
}
}
}
}
delete(element)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment