diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index e97f69c3..8dac03b3 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -3242,8 +3242,8 @@ "$(inherited)", "@executable_path/Frameworks", ); + MARKETING_VERSION = 1.4.4; PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltStore; - MARKETING_VERSION = 1.4.3b2; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "AltStore/AltStore-Bridging-Header.h"; @@ -3270,8 +3270,8 @@ "$(inherited)", "@executable_path/Frameworks", ); + MARKETING_VERSION = 1.4.4; PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltStore; - MARKETING_VERSION = 1.4.3b2; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "AltStore/AltStore-Bridging-Header.h"; diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index ca241cce..7785f37d 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -667,12 +667,17 @@ private extension AppManager case .refresh(let app): // Check if backup app is installed in place of real app. let uti = UTTypeCopyDeclaration(app.installedBackupAppUTI as CFString)?.takeRetainedValue() as NSDictionary? - if app.certificateSerialNumber != group.context.certificate?.serialNumber || uti != nil || app.needsResign + + if app.certificateSerialNumber != group.context.certificate?.serialNumber || + uti != nil || + app.needsResign || + (group.context.server?.connectionType == .local && !UserDefaults.standard.localServerSupportsRefreshing) { // Resign app instead of just refreshing profiles because either: // * Refreshing using different certificate // * Backup app is still installed // * App explicitly needs resigning + // * Device is jailbroken and using AltDaemon on iOS 14.0 or later (b/c refreshing with provisioning profiles is broken) let installProgress = self._install(app, operation: operation, group: group) { (result) in self.finish(operation, result: result, group: group, progress: progress) @@ -1398,12 +1403,26 @@ private extension AppManager func run(_ operations: [Foundation.Operation], context: OperationContext?, requiresSerialQueue: Bool = false) { + // Reference to previous serial operation in context used to enforce FIFO, + // even if the operations become ready in a different order than submitted. + var previousSerialOperation: Foundation.Operation? = context?.operations.allObjects.filter { self.serialOperationQueue.operations.contains($0) }.last + for operation in operations { switch operation { case _ where requiresSerialQueue: fallthrough - case is InstallAppOperation, is RefreshAppOperation, is BackupAppOperation: self.serialOperationQueue.addOperation(operation) + case is InstallAppOperation, is RefreshAppOperation, is BackupAppOperation: + if let previousOperation = previousSerialOperation + { + // Add dependency on previous serial operation to enforce FIFO. + operation.addDependency(previousOperation) + } + + self.serialOperationQueue.addOperation(operation) + + previousSerialOperation = operation + default: self.operationQueue.addOperation(operation) } diff --git a/AltStoreCore/Extensions/UserDefaults+AltStore.swift b/AltStoreCore/Extensions/UserDefaults+AltStore.swift index 4c0dfe3d..db828fc6 100644 --- a/AltStoreCore/Extensions/UserDefaults+AltStore.swift +++ b/AltStoreCore/Extensions/UserDefaults+AltStore.swift @@ -33,6 +33,8 @@ public extension UserDefaults @NSManaged var isLegacyDeactivationSupported: Bool @NSManaged var activeAppLimitIncludesExtensions: Bool + @NSManaged var localServerSupportsRefreshing: Bool + var activeAppsLimit: Int? { get { return self._activeAppsLimit?.intValue @@ -56,10 +58,14 @@ public extension UserDefaults let isLegacyDeactivationSupported = !ProcessInfo.processInfo.isOperatingSystemAtLeast(ios13_5) let activeAppLimitIncludesExtensions = !ProcessInfo.processInfo.isOperatingSystemAtLeast(ios13_5) + let ios14 = OperatingSystemVersion(majorVersion: 14, minorVersion: 0, patchVersion: 0) + let localServerSupportsRefreshing = !ProcessInfo.processInfo.isOperatingSystemAtLeast(ios14) + let defaults = [ #keyPath(UserDefaults.isBackgroundRefreshEnabled): true, #keyPath(UserDefaults.isLegacyDeactivationSupported): isLegacyDeactivationSupported, #keyPath(UserDefaults.activeAppLimitIncludesExtensions): activeAppLimitIncludesExtensions, + #keyPath(UserDefaults.localServerSupportsRefreshing): localServerSupportsRefreshing, #keyPath(UserDefaults.requiresAppGroupMigration): true ]