mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Deactivating apps by removing their profiles no longer works on iOS 13.5. Instead, AltStore will now back up the app by temporarily replacing it with AltBackup, then remove the app from the phone.
92 lines
2.4 KiB
Swift
92 lines
2.4 KiB
Swift
//
|
|
// RefreshGroup.swift
|
|
// AltStore
|
|
//
|
|
// Created by Riley Testut on 6/20/19.
|
|
// Copyright © 2019 Riley Testut. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import CoreData
|
|
|
|
import AltSign
|
|
|
|
class RefreshGroup: NSObject
|
|
{
|
|
let context: AuthenticatedOperationContext
|
|
let progress = Progress.discreteProgress(totalUnitCount: 0)
|
|
|
|
var completionHandler: (([String: Result<InstalledApp, Error>]) -> Void)?
|
|
var beginInstallationHandler: ((InstalledApp) -> Void)?
|
|
|
|
private(set) var results = [String: Result<InstalledApp, Error>]()
|
|
|
|
// Keep strong references to managed object contexts
|
|
// so they don't die out from under us.
|
|
private(set) var _contexts = Set<NSManagedObjectContext>()
|
|
|
|
private var isFinished = false
|
|
|
|
private let dispatchGroup = DispatchGroup()
|
|
private var operations: [Foundation.Operation] = []
|
|
|
|
init(context: AuthenticatedOperationContext = AuthenticatedOperationContext())
|
|
{
|
|
self.context = context
|
|
|
|
super.init()
|
|
}
|
|
|
|
/// Used to keep track of which operations belong to this group.
|
|
/// This does _not_ add them to any operation queue.
|
|
func add(_ operations: [Foundation.Operation])
|
|
{
|
|
for operation in operations
|
|
{
|
|
self.dispatchGroup.enter()
|
|
|
|
operation.completionBlock = { [weak self] in
|
|
self?.dispatchGroup.leave()
|
|
}
|
|
}
|
|
|
|
if self.operations.isEmpty && !operations.isEmpty
|
|
{
|
|
self.dispatchGroup.notify(queue: .global()) { [weak self] in
|
|
self?.finish()
|
|
}
|
|
}
|
|
|
|
self.operations.append(contentsOf: operations)
|
|
}
|
|
|
|
func set(_ result: Result<InstalledApp, Error>, forAppWithBundleIdentifier bundleIdentifier: String)
|
|
{
|
|
self.results[bundleIdentifier] = result
|
|
|
|
switch result
|
|
{
|
|
case .failure: break
|
|
case .success(let installedApp):
|
|
guard let context = installedApp.managedObjectContext else { break }
|
|
self._contexts.insert(context)
|
|
}
|
|
}
|
|
|
|
func cancel()
|
|
{
|
|
self.operations.forEach { $0.cancel() }
|
|
}
|
|
}
|
|
|
|
private extension RefreshGroup
|
|
{
|
|
func finish()
|
|
{
|
|
guard !self.isFinished else { return }
|
|
self.isFinished = true
|
|
|
|
self.completionHandler?(self.results)
|
|
}
|
|
}
|