From 381e09d87c7eaa1a218824f35311ecc9039239ac Mon Sep 17 00:00:00 2001 From: Huge_Black Date: Tue, 24 Feb 2026 13:58:19 +0800 Subject: [PATCH 1/5] bug-fix: Fix crash when installing apps --- AltStore/AppDelegate.swift | 1 - SideStore/MinimuxerWrapper.swift | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AltStore/AppDelegate.swift b/AltStore/AppDelegate.swift index 81c2ff23..e8fb984c 100644 --- a/AltStore/AppDelegate.swift +++ b/AltStore/AppDelegate.swift @@ -92,7 +92,6 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { } } - self.setTintColor() self.setTintColor() self.prepareImageCache() diff --git a/SideStore/MinimuxerWrapper.swift b/SideStore/MinimuxerWrapper.swift index e585dc11..7441fdb0 100644 --- a/SideStore/MinimuxerWrapper.swift +++ b/SideStore/MinimuxerWrapper.swift @@ -55,7 +55,8 @@ func yeetAppAFC(_ bundleId: String, _ rawBytes: Data) throws { #if targetEnvironment(simulator) print("yeetAppAFC(\(bundleId), \(rawBytes)) is no-op on simulator") #else - try minimuxer.yeet_app_afc(bundleId, rawBytes.toRustByteSlice().forRust()) + let slice = rawBytes.toRustByteSlice() + try minimuxer.yeet_app_afc(bundleId, slice.forRust()) #endif } From c2cecb63ac96f035ef92db22c8c9a46ff41bb535 Mon Sep 17 00:00:00 2001 From: Huge_Black Date: Tue, 24 Feb 2026 14:06:28 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=C2=A0bug-fix:=20fix=20useMainProfile=20not?= =?UTF-8?q?=20saved=20/=20not=20set=20during=20initialization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SideStore is killed by iOS before CoreData commit changes to db. Detect if the app is installed with useMainProfile by checking if applicationIdentifier matches --- AltStore/Operations/InstallAppOperation.swift | 7 ++++ .../DatabaseManager/DatabaseManager.swift | 34 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/AltStore/Operations/InstallAppOperation.swift b/AltStore/Operations/InstallAppOperation.swift index 547eccec..0f1e47bd 100644 --- a/AltStore/Operations/InstallAppOperation.swift +++ b/AltStore/Operations/InstallAppOperation.swift @@ -176,6 +176,13 @@ final class InstallAppOperation: ResultOperation var installing = true if installedApp.storeApp?.bundleIdentifier.range(of: Bundle.Info.appbundleIdentifier) != nil { + do { + // we need to flush changes to the disk now in case the changes are lost when iOS kills current process + try installedApp.managedObjectContext?.save() + } catch { + print("Failed to flush installedApp to disk: \(error)") + } + // Reinstalling ourself will hang until we leave the app, so we need to exit it without force closing DispatchQueue.main.asyncAfter(deadline: .now() + 3) { if UIApplication.shared.applicationState != .active { diff --git a/AltStoreCore/Model/DatabaseManager/DatabaseManager.swift b/AltStoreCore/Model/DatabaseManager/DatabaseManager.swift index 0dd2080c..bd41b077 100644 --- a/AltStoreCore/Model/DatabaseManager/DatabaseManager.swift +++ b/AltStoreCore/Model/DatabaseManager/DatabaseManager.swift @@ -399,6 +399,40 @@ private extension DatabaseManager // For backwards compatibility reasons, we cannot use localApp's buildVersion as storeBuildVersion, // or else the latest update will _always_ be considered new because we don't use buildVersions in our source (yet). installedApp = InstalledApp(resignedApp: localApp, originalBundleIdentifier: StoreApp.altstoreAppID, certificateSerialNumber: serialNumber, storeBuildVersion: nil, context: context) + + // figure out if the current AltStoreApp is signed with "Use Main Profie" option + // by checking if the first extension's entitlement's application-identifier matches current one + repeat { + guard let pluginURL = Bundle.main.builtInPlugInsURL else { + installedApp.useMainProfile = true + break + } + guard let pluginFolders = try? FileManager.default.contentsOfDirectory(at: pluginURL, includingPropertiesForKeys: nil) else { + installedApp.useMainProfile = true + break + } + + guard let pluginFolder = pluginFolders.first, let altPluginApp = ALTApplication(fileURL: pluginFolder) else { + installedApp.useMainProfile = true + break + } + + let entitlements = altPluginApp.entitlements + guard let appId = entitlements[ALTEntitlement.applicationIdentifier] as? String else { + installedApp.useMainProfile = false + print("no ALTEntitlementApplicationIdentifier???") + break + } + + if appId.hasSuffix(Bundle.main.bundleIdentifier!) { + installedApp.useMainProfile = true + } else { + installedApp.useMainProfile = false + } + + + } while(false) + installedApp.storeApp = storeApp } From e27d44eece6d1c0c1030045e5e104a4183de1c70 Mon Sep 17 00:00:00 2001 From: Huge_Black Date: Tue, 24 Feb 2026 14:30:03 +0800 Subject: [PATCH 3/5] fix build issue --- AltStore/Browse/FeaturedViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AltStore/Browse/FeaturedViewController.swift b/AltStore/Browse/FeaturedViewController.swift index e217ede2..c1f5eaf9 100644 --- a/AltStore/Browse/FeaturedViewController.swift +++ b/AltStore/Browse/FeaturedViewController.swift @@ -368,7 +368,7 @@ private extension FeaturedViewController #keyPath(StoreApp._source._apps), #keyPath(StoreApp.bundleIdentifier), StoreApp.altstoreAppID, - #keyPath(StoreApp.installedApp), + #keyPath(StoreApp.installedApp) ) let primaryFetchRequest = fetchRequest.copy() as! NSFetchRequest From a54881a1c89c081094911bd6bf9a4c55513fec9b Mon Sep 17 00:00:00 2001 From: Huge_Black Date: Tue, 24 Feb 2026 15:39:42 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=C2=A0bug-fix:=20fix=20profile=20not=20inst?= =?UTF-8?q?alled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SideStore/MinimuxerWrapper.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SideStore/MinimuxerWrapper.swift b/SideStore/MinimuxerWrapper.swift index 7441fdb0..02671b91 100644 --- a/SideStore/MinimuxerWrapper.swift +++ b/SideStore/MinimuxerWrapper.swift @@ -37,7 +37,8 @@ func installProvisioningProfiles(_ profileData: Data) throws { #if targetEnvironment(simulator) print("installProvisioningProfiles(\(profileData)) is no-op on simulator") #else - try minimuxer.install_provisioning_profile(profileData.toRustByteSlice().forRust()) + let slice = profileData.toRustByteSlice() + try minimuxer.install_provisioning_profile(slice.forRust()) #endif } From d356045b5d6cbb179246e50ce9f73cb319493966 Mon Sep 17 00:00:00 2001 From: Huge_Black Date: Tue, 24 Feb 2026 15:41:18 +0800 Subject: [PATCH 5/5] bug-fix: fix crash when viewing app ids --- AltStore.xcodeproj/project.pbxproj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 211cc94b..0667acfa 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -2413,6 +2413,13 @@ /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 177EF33D2F4D8B8E008CAAE1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + "NSAttributedString+Markdown.m", + ); + target = BFD247692284B9A500981D42 /* SideStore */; + }; A8A5AFBE2F4C33A300572B4A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( @@ -2670,7 +2677,7 @@ /* Begin PBXFileSystemSynchronizedRootGroup section */ A8A5AC9D2F4C338F00572B4A /* Roxas */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Roxas; sourceTree = ""; }; - A8A5ACE42F4C339400572B4A /* MarkdownAttributedString */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = MarkdownAttributedString; sourceTree = ""; }; + A8A5ACE42F4C339400572B4A /* MarkdownAttributedString */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (177EF33D2F4D8B8E008CAAE1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MarkdownAttributedString; sourceTree = ""; }; A8A5AE1B2F4C33A300572B4A /* libplist */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (A8A5AFC02F4C33A300572B4A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = libplist; sourceTree = ""; }; A8A5AE662F4C33A300572B4A /* libimobiledevice-glue */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (A8A5AFBF2F4C33A300572B4A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = "libimobiledevice-glue"; sourceTree = ""; }; A8A5AF5E2F4C33A300572B4A /* libimobiledevice */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (A8A5AFBE2F4C33A300572B4A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = libimobiledevice; sourceTree = ""; };