ios/AuthenticatorBridgeKit/NSManagedObjectContext+Extension.swift

53 lines
2.0 KiB
Swift

import CoreData
extension NSManagedObjectContext {
/// Executes the batch delete request and/or batch insert request and merges any changes into
/// the current context plus any additional contexts.
///
/// - Parameters:
/// - batchDeleteRequest: The batch delete request to execute.
/// - batchInsertRequest: The batch insert request to execute.
/// - additionalContexts: Any additional contexts other than the current to merge the changes into.
///
func executeAndMergeChanges(
batchDeleteRequest: NSBatchDeleteRequest? = nil,
batchInsertRequest: NSBatchInsertRequest? = nil,
additionalContexts: [NSManagedObjectContext] = []
) throws {
var changes: [AnyHashable: Any] = [:]
if let batchDeleteRequest {
batchDeleteRequest.resultType = .resultTypeObjectIDs
if let deleteResult = try execute(batchDeleteRequest) as? NSBatchDeleteResult {
changes[NSDeletedObjectsKey] = deleteResult.result as? [NSManagedObjectID] ?? []
}
}
if let batchInsertRequest {
batchInsertRequest.resultType = .objectIDs
if let insertResult = try execute(batchInsertRequest) as? NSBatchInsertResult {
changes[NSInsertedObjectsKey] = insertResult.result as? [NSManagedObjectID] ?? []
}
}
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self] + additionalContexts)
}
/// Performs the closure on the context's queue and saves the context if there are any changes.
///
/// - Parameter closure: The closure to perform.
///
func performAndSave(closure: @escaping () throws -> Void) async throws {
try await perform {
try closure()
try self.saveIfChanged()
}
}
/// Saves the context if there are changes.
func saveIfChanged() throws {
guard hasChanges else { return }
try save()
}
}