From 24dd473291e689da017a284235529cdefd054337 Mon Sep 17 00:00:00 2001 From: Cody Kerns Date: Thu, 27 Aug 2020 10:45:41 -0400 Subject: [PATCH 1/3] Support iOS 9.3 minimum --- Package.swift | 2 +- Sources/PurchasesHelper/PackageExtensions.swift | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Package.swift b/Package.swift index c5de2ad..e6fae02 100644 --- a/Package.swift +++ b/Package.swift @@ -6,7 +6,7 @@ import PackageDescription let package = Package( name: "PurchasesHelper", platforms: [ - .iOS("11.2"), .watchOS("6.2") + .iOS("9.3"), .watchOS("6.2") ], products: [ // Products define the executables and libraries produced by a package, and make them visible to other packages. diff --git a/Sources/PurchasesHelper/PackageExtensions.swift b/Sources/PurchasesHelper/PackageExtensions.swift index f9cc055..863030d 100644 --- a/Sources/PurchasesHelper/PackageExtensions.swift +++ b/Sources/PurchasesHelper/PackageExtensions.swift @@ -24,7 +24,9 @@ public extension Purchases.Package { } // - check for an introductory discount for a package - if let intro = self.product.introductoryPrice { + if #available(iOS 11.2, *), + let intro = self.product.introductoryPrice { + // - introductory offers let introLengthTitle = intro.subscriptionPeriod.periodLengthTitle @@ -76,13 +78,18 @@ public extension Array where Element: Purchases.Package { return self.sorted(by: { $0.packageType.rawValue < $1.packageType.rawValue }) case .hasIntroductoryPrice: // 3 day trial, yearly -> weekly -> monthly - return self.sorted(by: { - return $0.product.introductoryPrice != nil && $1.product.introductoryPrice == nil - }) + if #available(iOS 11.2, *) { + return self.sorted(by: { + return $0.product.introductoryPrice != nil && $1.product.introductoryPrice == nil + }) + } else { + return self.sorted(by: .timeAscending) + } } } } +@available(iOS 11.2, *) fileprivate extension SKProductSubscriptionPeriod { var periodLengthTitle: String { let isPlural = numberOfUnits != 1 @@ -90,6 +97,7 @@ fileprivate extension SKProductSubscriptionPeriod { } } +@available(iOS 11.2, *) fileprivate extension SKProductDiscount { func periodLengthTitle(for unit: SKProduct.PeriodUnit) -> String { let isPlural = numberOfPeriods != 1 @@ -97,6 +105,7 @@ fileprivate extension SKProductDiscount { } } +@available(iOS 11.2, *) fileprivate extension SKProduct.PeriodUnit { var title: String { switch self { From bdca202015dd04c2455d650bf06bdd8c44410e2f Mon Sep 17 00:00:00 2001 From: Cody Kerns Date: Thu, 27 Aug 2020 10:48:10 -0400 Subject: [PATCH 2/3] Update readme for iOS 11.2 features and .configure fix --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5392862..024cf0a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ The easiest way to get started is to call `configure` on the shared instance of ```swift -CompatibilityAccessManager.shared.configure(entitlements: [ +CompatibilityAccessManager.configure(entitlements: [ .init(entitlement: "premium_access", versions: ["50"]) ]) @@ -122,4 +122,4 @@ The available sorting options are: > Sorts by longest duration -> shortest duration > **.hasIntroductoryPrice** -> Sorts by packages that have an introductory price (e.g. free trial) first +> Sorts by packages that have an introductory price (e.g. free trial) first. Requires iOS 11.2 minimum. From cfa8575ed9d6fc5b558fc9cd491a7491c82c0e1e Mon Sep 17 00:00:00 2001 From: Cody Kerns Date: Thu, 27 Aug 2020 10:53:44 -0400 Subject: [PATCH 3/3] Make .configure non-static --- README.md | 2 +- .../CompatibilityAccessManager.swift | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 024cf0a..5f86123 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ The easiest way to get started is to call `configure` on the shared instance of ```swift -CompatibilityAccessManager.configure(entitlements: [ +CompatibilityAccessManager.shared.configure(entitlements: [ .init(entitlement: "premium_access", versions: ["50"]) ]) diff --git a/Sources/PurchasesHelper/CompatibilityAccessManager.swift b/Sources/PurchasesHelper/CompatibilityAccessManager.swift index fc108cd..c9e9c8e 100644 --- a/Sources/PurchasesHelper/CompatibilityAccessManager.swift +++ b/Sources/PurchasesHelper/CompatibilityAccessManager.swift @@ -39,38 +39,37 @@ public class CompatibilityAccessManager { /** Optional configuration call to set entitlement versions as well as restore transactions if a receipt is available. **IMPORTANT**: this method should be called *after* you initialize the Purchases SDK. */ - public static func configure(entitlements: [BackwardsCompatibilityEntitlement], completion: ((Purchases.PurchaserInfo?) -> Void)? = nil) { - let manager = CompatibilityAccessManager.shared + public func configure(entitlements: [BackwardsCompatibilityEntitlement], completion: ((Purchases.PurchaserInfo?) -> Void)? = nil) { entitlements.forEach { (entitlement) in - CompatibilityAccessManager.shared.register(entitlement: entitlement) + self.register(entitlement: entitlement) } /// If we don't have an originalApplicationVersion in the Purchases SDK, and we have a receipt available, automatically restore transactions to ensure a value for originalApplicationVersion in PurchaserInfo - manager.log("Fetching PurchaserInfo.") + self.log("Fetching PurchaserInfo.") Purchases.shared.purchaserInfo { (info, error) in if let originalApplicationVersion = info?.originalApplicationVersionFixed { - manager.log("originalApplicationVersion is \(originalApplicationVersion)") + self.log("originalApplicationVersion is \(originalApplicationVersion)") completion?(info) } else { - manager.log("originalApplicationVersion is nil - checking for a receipt..") + self.log("originalApplicationVersion is nil - checking for a receipt..") if let receiptURL = Bundle.main.appStoreReceiptURL, let _ = try? Data(contentsOf: receiptURL) { - manager.log("Receipt data found. Syncing with Purchases..") + self.log("Receipt data found. Syncing with Purchases..") Purchases.shared.restoreTransactions { (info, error) in if error == nil { - manager.log("Receipt synced.") + self.log("Receipt synced.") } completion?(info) } } else { - manager.log("No receipt data found.") + self.log("No receipt data found.") /// No receipt data - restoreTransactions will need to be called manually as it will likely require a sign-in completion?(nil)