From 731d382af81d565ace16454606afd603caa7930f Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Thu, 11 May 2023 14:45:09 -0500 Subject: [PATCH] [AltStoreCore] Adds Managed.perform() to match AsyncManaged --- AltStoreCore/Types/Managed.swift | 43 +++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/AltStoreCore/Types/Managed.swift b/AltStoreCore/Types/Managed.swift index a7a11f48..d591e5ae 100644 --- a/AltStoreCore/Types/Managed.swift +++ b/AltStoreCore/Types/Managed.swift @@ -32,41 +32,66 @@ public struct Managed self.wrappedValue = wrappedValue self.managedObjectContext = self.managedObject?.managedObjectContext } - - public subscript(dynamicMember keyPath: KeyPath) -> T +} + +/// Run on managedObjectContext's queue. +public extension Managed +{ + // Non-throwing + func perform(_ closure: @escaping (ManagedObject) -> T) -> T { var result: T! if let context = self.managedObjectContext { context.performAndWait { - result = self.wrappedValue[keyPath: keyPath] + result = closure(self.wrappedValue) } } else { - result = self.wrappedValue[keyPath: keyPath] + result = closure(self.wrappedValue) } return result } - // Optionals - public subscript(dynamicMember keyPath: KeyPath) -> T? where ManagedObject == Optional + // Throwing + func perform(_ closure: @escaping (ManagedObject) throws -> T) throws -> T { - var result: T? + var result: Result! if let context = self.managedObjectContext { context.performAndWait { - result = self.wrappedValue?[keyPath: keyPath] as? T + result = Result { try closure(self.wrappedValue) } } } else { - result = self.wrappedValue?[keyPath: keyPath] as? T + result = Result { try closure(self.wrappedValue) } } + let value = try result.get() + return value + } +} + +/// @dynamicMemberLookup +public extension Managed +{ + subscript(dynamicMember keyPath: KeyPath) -> T + { + let result = self.perform { $0[keyPath: keyPath] } + return result + } + + // Optionals + subscript(dynamicMember keyPath: KeyPath) -> T? where ManagedObject == Optional + { + guard let wrappedValue else { return nil } + + let result = self.perform { _ in wrappedValue[keyPath: keyPath] } return result } }