From a09f4bbd7a87bc08c2facb1ff0cb248eb5b81d5a Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Thu, 11 May 2023 14:41:01 -0500 Subject: [PATCH] [AltStoreCore] Renames AsyncManaged.get() to perform() Implies it can be used as alternative to managedObject.managedObjectContext.perform() and not just for retrieving values. --- AltStore/Managing Apps/AppManager.swift | 4 +-- AltStoreCore/Types/AsyncManaged.swift | 44 +++++++++++++++---------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index 48a9ad91..839ad3c5 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -355,7 +355,7 @@ extension AppManager func add(@AsyncManaged _ source: Source, message: String? = nil, presentingViewController: UIViewController) async throws { - let (sourceName, sourceURL) = await $source.get { ($0.name, $0.sourceURL) } + let (sourceName, sourceURL) = await $source.perform { ($0.name, $0.sourceURL) } let context = DatabaseManager.shared.persistentContainer.newBackgroundContext() async let fetchedSource = try await self.fetchSource(sourceURL: sourceURL, managedObjectContext: context) // Fetch source async while showing alert. @@ -375,7 +375,7 @@ extension AppManager func remove(@AsyncManaged _ source: Source, presentingViewController: UIViewController) async throws { - let (sourceName, sourceID) = await $source.get { ($0.name, $0.identifier) } + let (sourceName, sourceID) = await $source.perform { ($0.name, $0.identifier) } guard sourceID != Source.altStoreIdentifier else { throw OperationError.forbidden(failureReason: NSLocalizedString("The default AltStore source cannot be removed.", comment: "")) } diff --git a/AltStoreCore/Types/AsyncManaged.swift b/AltStoreCore/Types/AsyncManaged.swift index 1be2937b..a97341f2 100644 --- a/AltStoreCore/Types/AsyncManaged.swift +++ b/AltStoreCore/Types/AsyncManaged.swift @@ -34,10 +34,11 @@ public struct AsyncManaged } } +/// Run on managedObjectContext's queue. public extension AsyncManaged { - // Fetch multiple values. - func get(_ closure: @escaping (ManagedObject) -> T) async -> T + // Non-throwing + func perform(_ closure: @escaping (ManagedObject) -> T) async -> T { if let context = self.managedObjectContext { @@ -50,33 +51,40 @@ public extension AsyncManaged return closure(self.wrappedValue) } } + + // Throwing + func perform(_ closure: @escaping (ManagedObject) throws -> T) async throws -> T + { + if let context = self.managedObjectContext + { + return try await context.performAsync { + try closure(self.wrappedValue) + } + } + else + { + return try closure(self.wrappedValue) + } + } } /// @dynamicMemberLookup -extension AsyncManaged +public extension AsyncManaged { - public subscript(dynamicMember keyPath: KeyPath) -> T { + subscript(dynamicMember keyPath: KeyPath) -> T { get async { - guard let context = self.managedObjectContext else { - return self.wrappedValue[keyPath: keyPath] - } - - return await context.performAsync { - return self.wrappedValue[keyPath: keyPath] - } + let result = await self.perform { $0[keyPath: keyPath] } + return result } } // Optionals - public subscript(dynamicMember keyPath: KeyPath) -> T? where ManagedObject == Optional { + subscript(dynamicMember keyPath: KeyPath) -> T? where ManagedObject == Optional { get async { - guard let context = self.managedObjectContext else { - return self.wrappedValue?[keyPath: keyPath] - } + guard let wrappedValue else { return nil } - return await context.performAsync { - return self.wrappedValue?[keyPath: keyPath] - } + let result = await self.perform { _ in wrappedValue[keyPath: keyPath] } + return result } } }