From c2048f3814f6452fe51afb82fbf2e33e22075230 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Mon, 13 Jan 2020 11:22:40 -0800 Subject: [PATCH] Prevents deleting legacy sideloaded apps --- .../Extensions/UserDefaults+AltStore.swift | 2 ++ AltStore/Managing Apps/AppManager.swift | 24 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/AltStore/Extensions/UserDefaults+AltStore.swift b/AltStore/Extensions/UserDefaults+AltStore.swift index ba49046a..828989f8 100644 --- a/AltStore/Extensions/UserDefaults+AltStore.swift +++ b/AltStore/Extensions/UserDefaults+AltStore.swift @@ -20,6 +20,8 @@ extension UserDefaults @NSManaged var isDebugModeEnabled: Bool @NSManaged var presentedLaunchReminderNotification: Bool + @NSManaged var legacySideloadedApps: [String]? + func registerDefaults() { self.register(defaults: [#keyPath(UserDefaults.isBackgroundRefreshEnabled): true]) diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index 654d66ab..8206b482 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -56,6 +56,18 @@ extension AppManager do { let installedApps = try context.fetch(fetchRequest) + + if UserDefaults.standard.legacySideloadedApps == nil + { + // First time updating apps since updating AltStore to use custom UTIs, + // so cache all existing apps temporarily to prevent us from accidentally + // deleting them due to their custom UTI not existing (yet). + let apps = installedApps.map { $0.bundleIdentifier } + UserDefaults.standard.legacySideloadedApps = apps + } + + let legacySideloadedApps = Set(UserDefaults.standard.legacySideloadedApps ?? []) + for app in installedApps { let uti = UTTypeCopyDeclaration(app.installedAppUTI as CFString)?.takeRetainedValue() as NSDictionary? @@ -66,12 +78,10 @@ extension AppManager } else { - if uti == nil && !UIApplication.shared.canOpenURL(app.openAppURL) + if uti == nil && !legacySideloadedApps.contains(app.bundleIdentifier) { // This UTI is not declared by any apps, which means this app has been deleted by the user. - // We also check canOpenURL as a fallback for apps installed before we switched to using custom UTIs. - // canOpenURL always returns NO for apps not declared in our Info.plist, - // so it should not affect UTI-based installation checks. + // This app is also not a legacy sideloaded app, so we can assume it's fine to delete it. context.delete(app) } } @@ -428,6 +438,12 @@ private extension AppManager do { try installedApp.managedObjectContext?.save() } catch { print("Error saving installed app.", error) } } + + if let index = UserDefaults.standard.legacySideloadedApps?.firstIndex(of: installedApp.bundleIdentifier) + { + // No longer a legacy sideloaded app, so remove it from cached list. + UserDefaults.standard.legacySideloadedApps?.remove(at: index) + } } print("Finished operation!", context.bundleIdentifier)