-
-
Save georgescumihai/5c7e93322c59e6808c671bc65beaa221 to your computer and use it in GitHub Desktop.
Cascade deletion for realm.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This solution is an adaption of from https://gist.github.com/verebes1/02950e46fff91456f2ad359b3f3ec3d9 | |
// It is for Objective-C | |
// With the fix for objects with same hash. | |
import Foundation | |
import Realm | |
/// Cascade deletion for realm. | |
public extension RLMRealm { | |
/// Delete a realm object and his child objects. | |
/// - Parameter object: object to be deleted. | |
/// - Parameter cascade: true if the deletion should remove the child objects, otherwise false. | |
@objc func deleteObject(_ object: RLMObject, cascade: Bool) { | |
guard cascade else { | |
delete(object) | |
return | |
} | |
cascadeDelete([object]) | |
} | |
/// Cascade delete a realm objects array. | |
/// - Parameter objects: array with objects to be deleted. | |
/// - Parameter cascade: true if the deletion should remove the child objects, otherwise false. | |
func deleteObjects(_ objects: [RLMObject], cascade: Bool) { | |
guard cascade else { | |
objects.forEach(delete(_:)) | |
return | |
} | |
cascadeDelete(objects) | |
} | |
/// Cascade delete a realm collection. | |
/// - Parameter objects: enumeration with objects to be deleted. | |
/// - Parameter cascade: true if the deletion should remove the child objects, otherwise false. | |
@objc func deleteObjects(_ objects: NSFastEnumeration, cascade: Bool) { | |
// If cascade is false, then do a normal delete. | |
guard cascade else { | |
deleteObjects(objects) | |
return | |
} | |
var iterator = NSFastEnumerationIterator(objects) | |
while let element = iterator.next() { | |
guard let object = element as? RLMObject else { | |
continue | |
} | |
cascadeDelete([object]) | |
} | |
} | |
private func cascadeDelete(_ objects: [RLMObject]) { | |
var toBeDeleted = objects | |
while let element = toBeDeleted.popLast() { | |
guard !element.isInvalidated, element.realm != nil else { continue } | |
resolve(element: element, toBeDeleted: &toBeDeleted) | |
delete(element) | |
} | |
} | |
private func resolve(element: RLMObject, toBeDeleted: inout [RLMObject]) { | |
func foundChild(entity: RLMObject) { | |
toBeDeleted.append(entity) | |
} | |
func foundChild(collection: RLMCollection) { | |
(0..<collection.count) | |
.map(collection.object(at:)) | |
.compactMap { $0 as? RLMObject } | |
.forEach(foundChild) | |
} | |
element | |
.objectSchema | |
.properties | |
.map(\.name) | |
.compactMap(element.value(forKey:)) | |
.forEach { value in | |
if let entity = value as? RLMObject { | |
foundChild(entity: entity) | |
} else if let collection = value as? RLMCollection { | |
foundChild(collection: collection) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment