diff --git a/AltStore/Operations/Errors/SourceError.swift b/AltStore/Operations/Errors/SourceError.swift
index bbf0110d..648b7e3d 100644
--- a/AltStore/Operations/Errors/SourceError.swift
+++ b/AltStore/Operations/Errors/SourceError.swift
@@ -24,6 +24,9 @@ extension SourceError
case missingPermissionUsageDescription
case missingScreenshotSize
+
+ case marketplaceAppsNotSupported = 101
+ case marketplaceAppsRequired
}
static func unsupported(_ source: Source) -> SourceError { SourceError(code: .unsupported, source: source) }
@@ -41,6 +44,14 @@ extension SourceError
static func missingScreenshotSize(for screenshot: AppScreenshot, source: Source) -> SourceError {
SourceError(code: .missingScreenshotSize, source: source, app: screenshot.app, screenshotURL: screenshot.imageURL)
}
+
+ static func marketplaceAppsNotSupported(source: Source) -> SourceError {
+ return SourceError(code: .marketplaceAppsNotSupported, source: source)
+ }
+
+ static func marketplaceAppsRequired(source: Source) -> SourceError {
+ return SourceError(code: .marketplaceAppsRequired, source: source)
+ }
}
struct SourceError: ALTLocalizedError
@@ -128,6 +139,14 @@ struct SourceError: ALTLocalizedError
let failureReason = baseMessage + ": \(screenshotURL.absoluteString)"
return failureReason
+
+ case .marketplaceAppsNotSupported:
+ let failureReason = String(format: NSLocalizedString("The source “%@” contains notarized apps, which are not supported by this version of AltStore.", comment: ""), self.$source.name)
+ return failureReason
+
+ case .marketplaceAppsRequired:
+ let failureReason = String(format: NSLocalizedString("The source “%@” contains non-marketplace apps, which are not supported by this version of AltStore.", comment: ""), self.$source.name)
+ return failureReason
}
}
@@ -166,6 +185,10 @@ struct SourceError: ALTLocalizedError
let recoverySuggestion = NSLocalizedString("Please remove the existing source in order to add this one.", comment: "")
return recoverySuggestion
+ case .marketplaceAppsRequired:
+ let failureReason = String(format: NSLocalizedString("AltStore can only install marketplace apps that have been notarized by Apple.", comment: ""), self.$source.name)
+ return failureReason
+
default: return nil
}
}
diff --git a/AltStore/Operations/FetchSourceOperation.swift b/AltStore/Operations/FetchSourceOperation.swift
index 1eacc0eb..52866172 100644
--- a/AltStore/Operations/FetchSourceOperation.swift
+++ b/AltStore/Operations/FetchSourceOperation.swift
@@ -226,6 +226,12 @@ private extension FetchSourceOperation
// All iPad screenshots MUST have an explicit size.
guard screenshot.size != nil else { throw SourceError.missingScreenshotSize(for: screenshot, source: source) }
}
+
+ #if MARKETPLACE
+ guard app.marketplaceID != nil else { throw SourceError.marketplaceAppsRequired(source: source) }
+ #else
+ guard app.marketplaceID == nil else { throw SourceError.marketplaceAppsNotSupported(source: source) }
+ #endif
}
if let previousSourceID = self.$source.identifier
diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 16.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 16.xcdatamodel/contents
index e02a449e..f6b5f36c 100644
--- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 16.xcdatamodel/contents
+++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 16.xcdatamodel/contents
@@ -250,6 +250,7 @@
+
diff --git a/AltStoreCore/Model/StoreApp.swift b/AltStoreCore/Model/StoreApp.swift
index 2f374e79..005b271b 100644
--- a/AltStoreCore/Model/StoreApp.swift
+++ b/AltStoreCore/Model/StoreApp.swift
@@ -152,6 +152,9 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
@NSManaged public private(set) var tintColor: UIColor?
@NSManaged public private(set) var isBeta: Bool
+ // Required for Marketplace apps.
+ @NSManaged public private(set) var marketplaceID: String?
+
@NSManaged public var isPledged: Bool
@NSManaged public private(set) var isPledgeRequired: Bool
@NSManaged public private(set) var isHiddenWithoutPledge: Bool
@@ -275,6 +278,7 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
{
case name
case bundleIdentifier
+ case marketplaceID
case developerName
case localizedDescription
case iconURL
@@ -345,6 +349,8 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
} else {
throw DecodingError.dataCorruptedError(forKey: .downloadURL, in: container, debugDescription: "E downloadURL:String or downloadURLs:[[Platform:URL]] key required.")
}
+ // Required for Marketplace apps, but we'll verify later.
+ self.marketplaceID = try container.decodeIfPresent(String.self, forKey: .marketplaceID)
// else {
// throw DecodingError.dataCorruptedError(forKey: .downloadURL, in: container, debugDescription: "E downloadURL:String or downloadURLs:[[Platform:URL]] key required.")