diff --git a/AltStore/Model/DatabaseManager.swift b/AltStore/Model/DatabaseManager.swift index 323dae06..88d606ca 100644 --- a/AltStore/Model/DatabaseManager.swift +++ b/AltStore/Model/DatabaseManager.swift @@ -171,6 +171,32 @@ private extension DatabaseManager installedApp.storeApp = storeApp } + /* App Extensions */ + var installedExtensions = Set() + + for appExtension in localApp.appExtensions + { + let resignedBundleID = appExtension.bundleIdentifier + let originalBundleID = resignedBundleID.replacingOccurrences(of: localApp.bundleIdentifier, with: StoreApp.altstoreAppID) + + let installedExtension: InstalledExtension + + if let appExtension = installedApp.appExtensions.first(where: { $0.bundleIdentifier == originalBundleID }) + { + installedExtension = appExtension + } + else + { + installedExtension = InstalledExtension(resignedAppExtension: appExtension, originalBundleIdentifier: originalBundleID, context: context) + } + + installedExtension.update(resignedAppExtension: appExtension) + + installedExtensions.insert(installedExtension) + } + + installedApp.appExtensions = installedExtensions + let fileURL = installedApp.fileURL #if DEBUG @@ -181,16 +207,32 @@ private extension DatabaseManager if replaceCachedApp { + func update(_ bundle: Bundle, bundleID: String) throws + { + let infoPlistURL = bundle.bundleURL.appendingPathComponent("Info.plist") + + guard var infoDictionary = bundle.infoDictionary else { throw ALTError(.missingInfoPlist) } + infoDictionary[kCFBundleIdentifierKey as String] = bundleID + try (infoDictionary as NSDictionary).write(to: infoPlistURL) + } + FileManager.default.prepareTemporaryURL() { (temporaryFileURL) in do { try FileManager.default.copyItem(at: Bundle.main.bundleURL, to: temporaryFileURL) - let infoPlistURL = temporaryFileURL.appendingPathComponent("Info.plist") + guard let appBundle = Bundle(url: temporaryFileURL) else { throw ALTError(.invalidApp) } + try update(appBundle, bundleID: StoreApp.altstoreAppID) - guard var infoDictionary = Bundle.main.infoDictionary else { throw ALTError(.missingInfoPlist) } - infoDictionary[kCFBundleIdentifierKey as String] = StoreApp.altstoreAppID - try (infoDictionary as NSDictionary).write(to: infoPlistURL) + if let tempApp = ALTApplication(fileURL: temporaryFileURL) + { + for appExtension in tempApp.appExtensions + { + guard let extensionBundle = Bundle(url: appExtension.fileURL) else { throw ALTError(.invalidApp) } + guard let installedExtension = installedExtensions.first(where: { $0.resignedBundleIdentifier == appExtension.bundleIdentifier }) else { throw ALTError(.invalidApp) } + try update(extensionBundle, bundleID: installedExtension.bundleIdentifier) + } + } try FileManager.default.copyItem(at: temporaryFileURL, to: fileURL, shouldReplace: true) } diff --git a/AltStore/Operations/FetchProvisioningProfilesOperation.swift b/AltStore/Operations/FetchProvisioningProfilesOperation.swift index 9a3c0eab..a1729e20 100644 --- a/AltStore/Operations/FetchProvisioningProfilesOperation.swift +++ b/AltStore/Operations/FetchProvisioningProfilesOperation.swift @@ -132,7 +132,7 @@ extension FetchProvisioningProfilesOperation #if DEBUG - if app.bundleIdentifier == StoreApp.altstoreAppID || StoreApp.alternativeAltStoreAppIDs.contains(app.bundleIdentifier) + if app.bundleIdentifier.hasPrefix(StoreApp.altstoreAppID) || StoreApp.alternativeAltStoreAppIDs.contains(where: app.bundleIdentifier.hasPrefix) { // Use legacy bundle ID format for AltStore. preferredBundleID = "com.\(team.identifier).\(app.bundleIdentifier)" @@ -175,17 +175,19 @@ extension FetchProvisioningProfilesOperation // Or, if the app _is_ installed but with a different team, we need to create a new // bundle identifier anyway to prevent collisions with the previous team. let parentBundleID = parentApp?.bundleIdentifier ?? app.bundleIdentifier - let updatedParentBundleID = parentBundleID + "." + team.identifier // Append just team identifier to make it harder to track. + let updatedParentBundleID: String - if app.bundleIdentifier == StoreApp.altstoreAppID || StoreApp.alternativeAltStoreAppIDs.contains(app.bundleIdentifier) + if app.bundleIdentifier.hasPrefix(StoreApp.altstoreAppID) || StoreApp.alternativeAltStoreAppIDs.contains(where: app.bundleIdentifier.hasPrefix) { - // Use legacy bundle ID format for AltStore. - bundleID = "com.\(team.identifier).\(app.bundleIdentifier)" + // Use legacy bundle ID format for AltStore (and its extensions). + updatedParentBundleID = "com.\(team.identifier).\(parentBundleID)" } else { - bundleID = app.bundleIdentifier.replacingOccurrences(of: parentBundleID, with: updatedParentBundleID) + updatedParentBundleID = parentBundleID + "." + team.identifier // Append just team identifier to make it harder to track. } + + bundleID = app.bundleIdentifier.replacingOccurrences(of: parentBundleID, with: updatedParentBundleID) } let preferredName: String