mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Limits updating sources to app launch and manually via pull-to-refresh
This commit is contained in:
@@ -41,25 +41,21 @@ final class AppManagerPublisher: ObservableObject
|
||||
fileprivate(set) var refreshProgress = [String: Progress]()
|
||||
}
|
||||
|
||||
final class AppManager
|
||||
class AppManager: ObservableObject
|
||||
{
|
||||
static let shared = AppManager()
|
||||
|
||||
private(set) var updatePatronsResult: Result<Void, Error>?
|
||||
|
||||
|
||||
@Published
|
||||
private(set) var updateSourcesResult: Result<Void, Error>? // nil == loading
|
||||
|
||||
private let operationQueue = OperationQueue()
|
||||
private let serialOperationQueue = OperationQueue()
|
||||
|
||||
private var installationProgress = [String: Progress]() {
|
||||
didSet {
|
||||
self.publisher.installationProgress = self.installationProgress
|
||||
}
|
||||
}
|
||||
private var refreshProgress = [String: Progress]() {
|
||||
didSet {
|
||||
self.publisher.refreshProgress = self.refreshProgress
|
||||
}
|
||||
}
|
||||
@Published private var installationProgress = [String: Progress]()
|
||||
@Published private var refreshProgress = [String: Progress]()
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
private lazy var progressLock: UnsafeMutablePointer<os_unfair_lock> = {
|
||||
// Can't safely pass &os_unfair_lock to os_unfair_lock functions in Swift,
|
||||
@@ -70,9 +66,6 @@ final class AppManager
|
||||
return lock
|
||||
}()
|
||||
|
||||
private let publisher = AppManagerPublisher()
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
private init()
|
||||
{
|
||||
self.operationQueue.name = "com.altstore.AppManager.operationQueue"
|
||||
@@ -95,7 +88,7 @@ final class AppManager
|
||||
/// Every time refreshProgress is changed, update all InstalledApps in memory
|
||||
/// so that app.isRefreshing == refreshProgress.keys.contains(app.bundleID)
|
||||
|
||||
self.publisher.$refreshProgress
|
||||
self.$refreshProgress
|
||||
.receive(on: RunLoop.main)
|
||||
.map(\.keys)
|
||||
.flatMap { (bundleIDs) in
|
||||
@@ -547,6 +540,68 @@ extension AppManager
|
||||
self.run([updatePatronsOperation], context: nil)
|
||||
}
|
||||
|
||||
func updateAllSources(completion: @escaping (Result<Void, Error>) -> Void)
|
||||
{
|
||||
self.updateSourcesResult = nil
|
||||
|
||||
self.fetchSources() { (result) in
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
let (_, context) = try result.get()
|
||||
try context.save()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.updateSourcesResult = .success(())
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
catch let error as AppManager.FetchSourcesError
|
||||
{
|
||||
try error.managedObjectContext?.save()
|
||||
throw error
|
||||
}
|
||||
catch let mergeError as MergeError
|
||||
{
|
||||
guard let sourceID = mergeError.sourceID else { throw mergeError }
|
||||
|
||||
let sanitizedError = (mergeError as NSError).sanitizedForSerialization()
|
||||
DatabaseManager.shared.persistentContainer.performBackgroundTask { context in
|
||||
do
|
||||
{
|
||||
guard let source = Source.first(satisfying: NSPredicate(format: "%K == %@", #keyPath(Source.identifier), sourceID), in: context) else { return }
|
||||
|
||||
source.error = sanitizedError
|
||||
try context.save()
|
||||
}
|
||||
catch
|
||||
{
|
||||
Logger.main.error("Failed to assign error \(sanitizedError.localizedErrorCode) to source \(sourceID, privacy: .public). \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
throw mergeError
|
||||
}
|
||||
}
|
||||
catch var error as NSError
|
||||
{
|
||||
if error.localizedTitle == nil
|
||||
{
|
||||
error = error.withLocalizedTitle(NSLocalizedString("Unable to Refresh Store", comment: ""))
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.updateSourcesResult = .failure(error)
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension AppManager
|
||||
{
|
||||
@discardableResult
|
||||
func install<T: AppProtocol>(_ app: T, presentingViewController: UIViewController?, context: AuthenticatedOperationContext = AuthenticatedOperationContext(), completionHandler: @escaping (Result<InstalledApp, Error>) -> Void) -> RefreshGroup
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user