From 417837049f44e0e9a36464d514a66d64d2f3a7bc Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Wed, 15 Nov 2023 13:41:05 -0600 Subject: [PATCH] [AltStoreCore] Updates StoreApp to support Patreon-exclusive apps --- .../AltStore 14.xcdatamodel/contents | 8 +++- AltStoreCore/Model/Source.swift | 5 +- AltStoreCore/Model/StoreApp.swift | 48 +++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 14.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 14.xcdatamodel/contents index dc9d4873..461e84bd 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 14.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 14.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -188,6 +188,7 @@ + @@ -207,8 +208,13 @@ + + + + + diff --git a/AltStoreCore/Model/Source.swift b/AltStoreCore/Model/Source.swift index c733f555..0d493ec8 100644 --- a/AltStoreCore/Model/Source.swift +++ b/AltStoreCore/Model/Source.swift @@ -63,8 +63,9 @@ public class Source: NSManagedObject, Fetchable, Decodable /* Source Detail */ @NSManaged public var subtitle: String? - @NSManaged public var websiteURL: URL? @NSManaged public var localizedDescription: String? + @NSManaged public var websiteURL: URL? + @NSManaged public var patreonURL: URL? // Optional properties with fallbacks. // `private` to prevent accidentally using instead of `effective[PropertyName]` @@ -117,6 +118,7 @@ public class Source: NSManagedObject, Fetchable, Decodable case headerImageURL = "headerURL" case websiteURL = "website" case tintColor + case patreonURL case apps case news @@ -147,6 +149,7 @@ public class Source: NSManagedObject, Fetchable, Decodable self.localizedDescription = try container.decodeIfPresent(String.self, forKey: .localizedDescription) self.iconURL = try container.decodeIfPresent(URL.self, forKey: .iconURL) self.headerImageURL = try container.decodeIfPresent(URL.self, forKey: .headerImageURL) + self.patreonURL = try container.decodeIfPresent(URL.self, forKey: .patreonURL) if let tintColorHex = try container.decodeIfPresent(String.self, forKey: .tintColor) { diff --git a/AltStoreCore/Model/StoreApp.swift b/AltStoreCore/Model/StoreApp.swift index 2a5035f8..a25db30a 100644 --- a/AltStoreCore/Model/StoreApp.swift +++ b/AltStoreCore/Model/StoreApp.swift @@ -25,6 +25,18 @@ public extension StoreApp static let dolphinAppID = "me.oatmealdome.dolphinios-njb" } +extension StoreApp +{ + private struct PatreonParameters: Decodable + { + var pledge: Decimal? + var currency: String? + var tiers: Set? + var benefit: String? + var hidden: Bool? + } +} + @objc(StoreApp) public class StoreApp: NSManagedObject, Decodable, Fetchable { @@ -44,6 +56,14 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable @NSManaged public private(set) var tintColor: UIColor? @NSManaged public private(set) var isBeta: Bool + @NSManaged public var isPledged: Bool + @NSManaged public private(set) var isPledgeRequired: Bool + @NSManaged public private(set) var isHiddenWithoutPledge: Bool + @NSManaged public private(set) var pledgeCurrency: String? + + @nonobjc public var pledgeAmount: Decimal? { _pledgeAmount as? Decimal } + @NSManaged @objc(pledgeAmount) private var _pledgeAmount: NSDecimalNumber? + @NSManaged public var sortIndex: Int32 @objc public internal(set) var sourceIdentifier: String? { @@ -137,6 +157,7 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable case size case isBeta = "beta" case versions + case patreon // Legacy case version @@ -247,6 +268,33 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable in: context) try self.setVersions([appVersion]) } + + // Must _explicitly_ set to false to ensure it updates cached database value. + self.isPledged = false + + if let patreon = try container.decodeIfPresent(PatreonParameters.self, forKey: .patreon) + { + self.isPledgeRequired = true + self.isHiddenWithoutPledge = patreon.hidden ?? false // Default to showing Patreon apps + + if let pledge = patreon.pledge + { + self._pledgeAmount = pledge as NSDecimalNumber + self.pledgeCurrency = patreon.currency ?? "USD" // Only set pledge currency if explicitly given pledge. + } + else if patreon.pledge == nil && patreon.tiers == nil && patreon.benefit == nil + { + // No conditions, so default to pledgeAmount of 0 to simplify logic. + self._pledgeAmount = 0 as NSDecimalNumber + } + } + else + { + self.isPledgeRequired = false + self.isHiddenWithoutPledge = false + self._pledgeAmount = nil + self.pledgeCurrency = nil + } } catch {