From 43be34fd34749652507c985ff2a438c88c960f69 Mon Sep 17 00:00:00 2001 From: osy Date: Wed, 10 Jun 2020 14:58:25 -0700 Subject: [PATCH] Preserve device specific keys in Info.plist Apple's Info.plist support platform and device specific keys to augment existing keys. For example `UISupportedInterfaceOrientations~ipad` replaces `UISupportedInterfaceOrientations` when running on an iPad. By using Bundle.infoDictionary, Apple will pre-process the Info.plist and replace any key with its device specific variant. Since AltStore does not support iPad, this will strip out any iPad specific keys for the installing app. We add an extension Bundle.completeInfoDictionary that will return the original de-serialized dictionary including all the device specific keys. See: https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html#//apple_ref/doc/uid/TP40009254-SW9 --- AltKit/Bundle+AltStore.swift | 5 +++++ AltStore/Model/DatabaseManager.swift | 2 +- AltStore/Operations/ResignAppOperation.swift | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/AltKit/Bundle+AltStore.swift b/AltKit/Bundle+AltStore.swift index 110b20f5..0b62666f 100644 --- a/AltKit/Bundle+AltStore.swift +++ b/AltKit/Bundle+AltStore.swift @@ -38,4 +38,9 @@ public extension Bundle let infoPlistURL = self.bundleURL.appendingPathComponent("ALTCertificate.p12") return infoPlistURL } + + var completeInfoDictionary: [String : Any]? { + let infoPlistURL = self.infoPlistURL + return NSDictionary(contentsOf: infoPlistURL) as? [String : Any] + } } diff --git a/AltStore/Model/DatabaseManager.swift b/AltStore/Model/DatabaseManager.swift index 8a627651..908dbbc7 100644 --- a/AltStore/Model/DatabaseManager.swift +++ b/AltStore/Model/DatabaseManager.swift @@ -181,7 +181,7 @@ private extension DatabaseManager let infoPlistURL = temporaryFileURL.appendingPathComponent("Info.plist") - guard var infoDictionary = Bundle.main.infoDictionary else { throw ALTError(.missingInfoPlist) } + guard var infoDictionary = Bundle.main.completeInfoDictionary else { throw ALTError(.missingInfoPlist) } infoDictionary[kCFBundleIdentifierKey as String] = StoreApp.altstoreAppID try (infoDictionary as NSDictionary).write(to: infoPlistURL) diff --git a/AltStore/Operations/ResignAppOperation.swift b/AltStore/Operations/ResignAppOperation.swift index 3288d79e..869ef1b1 100644 --- a/AltStore/Operations/ResignAppOperation.swift +++ b/AltStore/Operations/ResignAppOperation.swift @@ -109,7 +109,7 @@ private extension ResignAppOperation { guard let identifier = bundle.bundleIdentifier else { throw ALTError(.missingAppBundle) } guard let profile = profiles[identifier] else { throw ALTError(.missingProvisioningProfile) } - guard var infoDictionary = bundle.infoDictionary else { throw ALTError(.missingInfoPlist) } + guard var infoDictionary = bundle.completeInfoDictionary else { throw ALTError(.missingInfoPlist) } infoDictionary[kCFBundleIdentifierKey as String] = profile.bundleIdentifier @@ -147,7 +147,7 @@ private extension ResignAppOperation progress.becomeCurrent(withPendingUnitCount: 1) guard let appBundle = Bundle(url: appBundleURL) else { throw ALTError(.missingAppBundle) } - guard let infoDictionary = appBundle.infoDictionary else { throw ALTError(.missingInfoPlist) } + guard let infoDictionary = appBundle.completeInfoDictionary else { throw ALTError(.missingInfoPlist) } var allURLSchemes = infoDictionary[Bundle.Info.urlTypes] as? [[String: Any]] ?? []