// // Contexts.swift // AltStore // // Created by Riley Testut on 6/20/19. // Copyright © 2019 Riley Testut. All rights reserved. // import Foundation import CoreData import Network import AltStoreCore import AltSign class OperationContext { var error: Error? var presentingViewController: UIViewController? let operations: NSHashTable init(error: Error? = nil, operations: [Foundation.Operation] = []) { self.error = error self.operations = NSHashTable.weakObjects() for operation in operations { self.operations.add(operation) } } convenience init(context: OperationContext) { self.init(error: context.error, operations: context.operations.allObjects) } } final class AuthenticatedOperationContext: OperationContext { var session: ALTAppleAPISession? var team: ALTTeam? var certificate: ALTCertificate? weak var authenticationOperation: AuthenticationOperation? convenience init(context: AuthenticatedOperationContext) { self.init(error: context.error, operations: context.operations.allObjects) self.session = context.session self.team = context.team self.certificate = context.certificate self.authenticationOperation = context.authenticationOperation } } @dynamicMemberLookup class AppOperationContext { let bundleIdentifier: String let authenticatedContext: AuthenticatedOperationContext var app: ALTApplication? var provisioningProfiles: [String: ALTProvisioningProfile]? var isFinished = false var error: Error? { get { return _error ?? self.authenticatedContext.error } set { _error = newValue if self.authenticatedContext.error == nil { // Assign newValue to authenticatedContext.error if the latter is nil. // This fixes some operations continuing even after an error has occured. self.authenticatedContext.error = newValue } } } private var _error: Error? init(bundleIdentifier: String, authenticatedContext: AuthenticatedOperationContext) { self.bundleIdentifier = bundleIdentifier self.authenticatedContext = authenticatedContext } subscript(dynamicMember keyPath: WritableKeyPath) -> T { return self.authenticatedContext[keyPath: keyPath] } } class InstallAppOperationContext: AppOperationContext { lazy var temporaryDirectory: URL = { let temporaryDirectory = FileManager.default.uniqueTemporaryURL() do { try FileManager.default.createDirectory(at: temporaryDirectory, withIntermediateDirectories: true, attributes: nil) } catch { self.error = error } return temporaryDirectory }() var ipaURL: URL? var resignedApp: ALTApplication? var installedApp: InstalledApp? { didSet { self.installedAppContext = self.installedApp?.managedObjectContext } } private var installedAppContext: NSManagedObjectContext? var beginInstallationHandler: ((InstalledApp) -> Void)? var alternateIconURL: URL? // Non-nil when installing from a source. @AsyncManaged var appVersion: AppVersion? }