Files
SideStore/SideStoreApp/Sources/SideStoreAppKit/Operations/RefreshGroup.swift

83 lines
2.2 KiB
Swift
Raw Normal View History

//
// RefreshGroup.swift
// AltStore
//
// Created by Riley Testut on 6/20/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import CoreData
2023-03-01 00:48:36 -05:00
import Foundation
import AltSign
2023-03-01 00:48:36 -05:00
import SideStoreCore
2023-03-01 19:09:33 -05:00
public final class RefreshGroup: NSObject {
let context: AuthenticatedOperationContext
let progress = Progress.discreteProgress(totalUnitCount: 0)
2023-03-01 00:48:36 -05:00
var completionHandler: (([String: Result<InstalledApp, Error>]) -> Void)?
var beginInstallationHandler: ((InstalledApp) -> Void)?
2023-03-01 00:48:36 -05:00
private(set) var results = [String: Result<InstalledApp, Error>]()
2023-03-01 00:48:36 -05:00
// Keep strong references to managed object contexts
// so they don't die out from under us.
private(set) var _contexts = Set<NSManagedObjectContext>()
2023-03-01 00:48:36 -05:00
private var isFinished = false
2023-03-01 00:48:36 -05:00
private let dispatchGroup = DispatchGroup()
private var operations: [Foundation.Operation] = []
2023-03-01 00:48:36 -05:00
2023-03-01 19:09:33 -05:00
public init(context: AuthenticatedOperationContext = AuthenticatedOperationContext()) {
self.context = context
2023-03-01 00:48:36 -05:00
super.init()
}
2023-03-01 00:48:36 -05:00
/// Used to keep track of which operations belong to this group.
/// This does _not_ add them to any operation queue.
2023-03-01 19:09:33 -05:00
public func add(_ operations: [Foundation.Operation]) {
2023-03-01 00:48:36 -05:00
for operation in operations {
dispatchGroup.enter()
operation.completionBlock = { [weak self] in
self?.dispatchGroup.leave()
}
}
2023-03-01 00:48:36 -05:00
if self.operations.isEmpty && !operations.isEmpty {
dispatchGroup.notify(queue: .global()) { [weak self] in
self?.finish()
}
}
2023-03-01 00:48:36 -05:00
self.operations.append(contentsOf: operations)
}
2023-03-01 00:48:36 -05:00
2023-03-01 19:09:33 -05:00
public func set(_ result: Result<InstalledApp, Error>, forAppWithBundleIdentifier bundleIdentifier: String) {
2023-03-01 00:48:36 -05:00
results[bundleIdentifier] = result
switch result {
case .failure: break
2023-03-01 00:48:36 -05:00
case let .success(installedApp):
guard let context = installedApp.managedObjectContext else { break }
2023-03-01 00:48:36 -05:00
_contexts.insert(context)
}
}
2023-03-01 00:48:36 -05:00
2023-03-01 19:09:33 -05:00
public func cancel() {
2023-03-01 00:48:36 -05:00
operations.forEach { $0.cancel() }
}
}
2023-03-01 00:48:36 -05:00
private extension RefreshGroup {
func finish() {
guard !isFinished else { return }
isFinished = true
completionHandler?(results)
}
}