From e70c51e36c83fed92ebde50a34ad025019af8029 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Tue, 8 Sep 2020 13:12:40 -0700 Subject: [PATCH] Updates UI when refreshing apps with Siri --- AltStore/Managing Apps/AppManager.swift | 54 ++++++++++++++++++- .../AltStore 7.xcdatamodel/contents | 5 +- AltStoreCore/Model/InstalledApp.swift | 3 ++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index b4d9d95b..d9a284ad 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -10,6 +10,8 @@ import Foundation import UIKit import UserNotifications import MobileCoreServices +import Intents +import Combine import AltStoreCore import AltSign @@ -22,15 +24,41 @@ extension AppManager static let expirationWarningNotificationID = "altstore-expiration-warning" } +@available(iOS 13, *) +class AppManagerPublisher: ObservableObject +{ + @Published + fileprivate(set) var installationProgress = [String: Progress]() + + @Published + fileprivate(set) var refreshProgress = [String: Progress]() +} + class AppManager { static let shared = AppManager() + @available(iOS 13, *) + private(set) lazy var publisher: AppManagerPublisher = AppManagerPublisher() + private let operationQueue = OperationQueue() private let serialOperationQueue = OperationQueue() + + private var installationProgress = [String: Progress]() { + didSet { + guard #available(iOS 13, *) else { return } + self.publisher.installationProgress = self.installationProgress + } + } + private var refreshProgress = [String: Progress]() { + didSet { + guard #available(iOS 13, *) else { return } + self.publisher.refreshProgress = self.refreshProgress + } + } - private var installationProgress = [String: Progress]() - private var refreshProgress = [String: Progress]() + @available(iOS 13.0, *) + private lazy var cancellables = Set() private init() { @@ -38,6 +66,28 @@ class AppManager self.serialOperationQueue.name = "com.altstore.AppManager.serialOperationQueue" self.serialOperationQueue.maxConcurrentOperationCount = 1 + + if #available(iOS 13, *) + { + self.prepareSubscriptions() + } + } + + @available(iOS 13, *) + func prepareSubscriptions() + { + self.publisher.$refreshProgress + .receive(on: RunLoop.main) + .map(\.keys) + .flatMap { (bundleIDs) in + DatabaseManager.shared.viewContext.registeredObjects.publisher + .compactMap { $0 as? InstalledApp } + .map { ($0, bundleIDs) } + } + .sink { (installedApp, bundleIDs) in + installedApp.isRefreshing = bundleIDs.contains(installedApp.bundleIdentifier) + } + .store(in: &self.cancellables) } } diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 7.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 7.xcdatamodel/contents index 7e9c5bfb..acc9846d 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 7.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 7.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -37,6 +37,7 @@ + @@ -162,7 +163,7 @@ - + diff --git a/AltStoreCore/Model/InstalledApp.swift b/AltStoreCore/Model/InstalledApp.swift index 8712c572..d9457df5 100644 --- a/AltStoreCore/Model/InstalledApp.swift +++ b/AltStoreCore/Model/InstalledApp.swift @@ -43,6 +43,9 @@ public class InstalledApp: NSManagedObject, InstalledAppProtocol @NSManaged public var certificateSerialNumber: String? + /* Transient */ + @NSManaged public var isRefreshing: Bool + /* Relationships */ @NSManaged public var storeApp: StoreApp? @NSManaged public var team: Team?