From 551c004476f963116cee7ab5b3baac237cb10319 Mon Sep 17 00:00:00 2001 From: Bogdan Seniuc Date: Tue, 17 Oct 2023 17:34:12 +0300 Subject: [PATCH] Use provisioning profile details instead of guessing active app limit --- AltStore/Managing Apps/AppManager.swift | 64 ++++++++++--------- AltStore/My Apps/MyAppsViewController.swift | 4 +- .../FetchProvisioningProfilesOperation.swift | 4 -- AltStore/Operations/InstallAppOperation.swift | 15 ++--- 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index fc28cfba..05e9c8d5 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -1027,6 +1027,32 @@ private extension AppManager verifyOperation.addDependency(downloadOperation) + /* Refresh Anisette Data */ + let refreshAnisetteDataOperation = FetchAnisetteDataOperation(context: group.context) + refreshAnisetteDataOperation.resultHandler = { (result) in + switch result + { + case .failure(let error): context.error = error + case .success(let anisetteData): group.context.session?.anisetteData = anisetteData + } + } + refreshAnisetteDataOperation.addDependency(verifyOperation) + + + /* Fetch Provisioning Profiles */ + let fetchProvisioningProfilesOperation = FetchProvisioningProfilesOperation(context: context) + fetchProvisioningProfilesOperation.additionalEntitlements = additionalEntitlements + fetchProvisioningProfilesOperation.resultHandler = { (result) in + switch result + { + case .failure(let error): context.error = error + case .success(let provisioningProfiles): context.provisioningProfiles = provisioningProfiles + } + } + fetchProvisioningProfilesOperation.addDependency(refreshAnisetteDataOperation) + progress.addChild(fetchProvisioningProfilesOperation.progress, withPendingUnitCount: 5) + + /* Deactivate Apps (if necessary) */ let deactivateAppsOperation = RSTAsyncBlockOperation { [weak self] (operation) in do @@ -1042,6 +1068,12 @@ private extension AppManager { throw error } + + guard let profiles = context.provisioningProfiles else { throw OperationError.invalidParameters } + if !profiles.contains(where: { $1.isFreeProvisioningProfile == true }) { + operation.finish() + return + } guard let app = context.app, let presentingViewController = context.authenticatedContext.presentingViewController else { throw OperationError.invalidParameters } @@ -1061,7 +1093,7 @@ private extension AppManager operation.finish() } } - deactivateAppsOperation.addDependency(verifyOperation) + deactivateAppsOperation.addDependency(fetchProvisioningProfilesOperation) /* Patch App */ @@ -1136,32 +1168,6 @@ private extension AppManager patchAppOperation.addDependency(deactivateAppsOperation) - /* Refresh Anisette Data */ - let refreshAnisetteDataOperation = FetchAnisetteDataOperation(context: group.context) - refreshAnisetteDataOperation.resultHandler = { (result) in - switch result - { - case .failure(let error): context.error = error - case .success(let anisetteData): group.context.session?.anisetteData = anisetteData - } - } - refreshAnisetteDataOperation.addDependency(patchAppOperation) - - - /* Fetch Provisioning Profiles */ - let fetchProvisioningProfilesOperation = FetchProvisioningProfilesOperation(context: context) - fetchProvisioningProfilesOperation.additionalEntitlements = additionalEntitlements - fetchProvisioningProfilesOperation.resultHandler = { (result) in - switch result - { - case .failure(let error): context.error = error - case .success(let provisioningProfiles): context.provisioningProfiles = provisioningProfiles - } - } - fetchProvisioningProfilesOperation.addDependency(refreshAnisetteDataOperation) - progress.addChild(fetchProvisioningProfilesOperation.progress, withPendingUnitCount: 5) - - /* Resign */ let resignAppOperation = ResignAppOperation(context: context) resignAppOperation.resultHandler = { (result) in @@ -1171,7 +1177,7 @@ private extension AppManager case .success(let resignedApp): context.resignedApp = resignedApp } } - resignAppOperation.addDependency(fetchProvisioningProfilesOperation) + resignAppOperation.addDependency(patchAppOperation) progress.addChild(resignAppOperation.progress, withPendingUnitCount: 20) @@ -1214,7 +1220,7 @@ private extension AppManager progress.addChild(installOperation.progress, withPendingUnitCount: 30) installOperation.addDependency(sendAppOperation) - let operations = [downloadOperation, verifyOperation, deactivateAppsOperation, patchAppOperation, refreshAnisetteDataOperation, fetchProvisioningProfilesOperation, resignAppOperation, sendAppOperation, installOperation] + let operations = [downloadOperation, verifyOperation, refreshAnisetteDataOperation, fetchProvisioningProfilesOperation, deactivateAppsOperation, patchAppOperation, resignAppOperation, sendAppOperation, installOperation] group.add(operations) self.run(operations, context: group.context) diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index b249ebf5..7bdd44a4 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -1460,7 +1460,7 @@ extension MyAppsViewController let registeredAppIDs = team.appIDs.count let maximumAppIDCount = 10 - let remainingAppIDs = max(maximumAppIDCount - registeredAppIDs, 0) + let remainingAppIDs = maximumAppIDCount - registeredAppIDs if remainingAppIDs == 1 { @@ -1471,7 +1471,7 @@ extension MyAppsViewController footerView.textLabel.text = String(format: NSLocalizedString("%@ App IDs Remaining", comment: ""), NSNumber(value: remainingAppIDs)) } - footerView.textLabel.isHidden = false + footerView.textLabel.isHidden = remainingAppIDs < 0 case .individual, .organization, .unknown: footerView.textLabel.isHidden = true @unknown default: break diff --git a/AltStore/Operations/FetchProvisioningProfilesOperation.swift b/AltStore/Operations/FetchProvisioningProfilesOperation.swift index 89663226..6cf75332 100644 --- a/AltStore/Operations/FetchProvisioningProfilesOperation.swift +++ b/AltStore/Operations/FetchProvisioningProfilesOperation.swift @@ -262,10 +262,6 @@ extension FetchProvisioningProfilesOperation { throw OperationError.maximumAppIDLimitReached(application: application, requiredAppIDs: requiredAppIDs, availableAppIDs: availableAppIDs, nextExpirationDate: expirationDate) } - else - { - throw ALTAppleAPIError(.maximumAppIDLimitReached) - } } } //App ID name must be ascii. If the name is not ascii, using bundleID instead diff --git a/AltStore/Operations/InstallAppOperation.swift b/AltStore/Operations/InstallAppOperation.swift index f4870609..d7bb0414 100644 --- a/AltStore/Operations/InstallAppOperation.swift +++ b/AltStore/Operations/InstallAppOperation.swift @@ -41,7 +41,8 @@ final class InstallAppOperation: ResultOperation guard let certificate = self.context.certificate, - let resignedApp = self.context.resignedApp + let resignedApp = self.context.resignedApp, + let provisioningProfiles = self.context.provisioningProfiles else { return self.finish(.failure(OperationError.invalidParameters)) } let backgroundContext = DatabaseManager.shared.persistentContainer.newBackgroundContext() @@ -116,8 +117,7 @@ final class InstallAppOperation: ResultOperation // Temporary directory and resigned .ipa no longer needed, so delete them now to ensure AltStore doesn't quit before we get the chance to. self.cleanUp() - var activeProfiles: Set? - if let sideloadedAppsLimit = UserDefaults.standard.activeAppsLimit + if let sideloadedAppsLimit = UserDefaults.standard.activeAppsLimit, provisioningProfiles.contains(where: { $1.isFreeProvisioningProfile == true }) { // When installing these new profiles, AltServer will remove all non-active profiles to ensure we remain under limit. @@ -142,11 +142,10 @@ final class InstallAppOperation: ResultOperation installedApp.isActive = false } } - - activeProfiles = Set(activeApps.flatMap { (installedApp) -> [String] in - let appExtensionProfiles = installedApp.appExtensions.map { $0.resignedBundleIdentifier } - return [installedApp.resignedBundleIdentifier] + appExtensionProfiles - }) + } + else + { + installedApp.isActive = true } var installing = true