Supports adding/removing source from SourceDetailViewController

This commit is contained in:
Riley Testut
2023-04-04 16:55:55 -05:00
committed by Magesh K
parent f44c3c18a2
commit 82cacb1b51
4 changed files with 293 additions and 1 deletions

View File

@@ -344,6 +344,61 @@ extension AppManager
extension AppManager
{
func fetchSource(sourceURL: URL, managedObjectContext: NSManagedObjectContext = DatabaseManager.shared.persistentContainer.newBackgroundContext()) async throws -> Source
{
try await withCheckedThrowingContinuation { continuation in
self.fetchSource(sourceURL: sourceURL, managedObjectContext: managedObjectContext) { result in
continuation.resume(with: result)
}
}
}
func add(@AsyncManaged _ source: Source, message: String? = nil, presentingViewController: UIViewController) async throws
{
let (sourceName, sourceURL) = await $source.get { ($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.
let title = String(format: NSLocalizedString("Would you like to add the source “%@”?", comment: ""), sourceName)
let message = message ?? NSLocalizedString("Make sure to only add sources that you trust.", comment: "")
let action = await UIAlertAction(title: NSLocalizedString("Add Source", comment: ""), style: .default)
try await presentingViewController.presentConfirmationAlert(title: title, message: message, primaryAction: action)
// Wait for fetch to finish before saving context.
_ = try await fetchedSource
try await context.performAsync {
try context.save()
}
}
func remove(@AsyncManaged _ source: Source, presentingViewController: UIViewController) async throws
{
let (sourceName, sourceID) = await $source.get { ($0.name, $0.identifier) }
guard sourceID != Source.altStoreIdentifier else {
throw OperationError.forbidden(failureReason: NSLocalizedString("The default AltStore source cannot be removed.", comment: ""))
}
let title = String(format: NSLocalizedString("Are you sure you want to remove the source “%@”?", comment: ""), sourceName)
let message = NSLocalizedString("Any apps you've installed from this source will remain, but they'll no longer receive any app updates.", comment: "")
let action = await UIAlertAction(title: NSLocalizedString("Remove Source", comment: ""), style: .destructive)
try await presentingViewController.presentConfirmationAlert(title: title, message: message, primaryAction: action)
let context = DatabaseManager.shared.persistentContainer.newBackgroundContext()
try await context.performAsync {
let predicate = NSPredicate(format: "%K == %@", #keyPath(Source.identifier), sourceID)
guard let source = Source.first(satisfying: predicate, in: context) else { return } // Doesn't exist == success.
context.delete(source)
try context.save()
}
}
}
extension AppManager
{
@available(*, renamed: "fetchSource(sourceURL:managedObjectContext:)")
func fetchSource(sourceURL: URL,
managedObjectContext: NSManagedObjectContext = DatabaseManager.shared.persistentContainer.newBackgroundContext(),
dependencies: [Foundation.Operation] = [],