Skip to content

Commit

Permalink
Using enum
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Aug 29, 2023
1 parent 8c4b54c commit d5d78b3
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 26 deletions.
29 changes: 26 additions & 3 deletions Sources/Misc/Deprecations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ extension CustomerInfo {

public extension Configuration.Builder {

/// Set `usesStoreKit2IfAvailable`. If `true`, the SDK will use StoreKit 2 APIs internally. If disabled, it will use StoreKit 1 APIs instead.
/// Set `storeKit2Setting`. If `true`, the SDK will use StoreKit 2 APIs internally. If disabled, it will use StoreKit 1 APIs instead.
/// - Parameter usesStoreKit2IfAvailable: enable StoreKit 2 on devices that support it.
/// Defaults to `false`.
/// - Important: This configuration flag has been deprecated, and will be replaced by automatic remote configuration in the future.
Expand All @@ -420,17 +420,40 @@ public extension Configuration.Builder {
return self
}

/// Set `storeKit2Setting`. If `true`, the SDK will use StoreKit 2 APIs internally. If disabled, it will use StoreKit 1 APIs instead.
/// - Parameter storeKitVersion: Set this to the StoreKit implementation your app uses for purchases.
/// I.e.: if your app uses `StoreKit 1`, set it to ``Configuration/StoreKitVersion/storeKit1``
/// and if your app uses `StoreKit 2`, set it to ``Configuration/StoreKitVersion/storeKit2``.
/// Apps using `StoreKit 1` use `SKPaymentQueue` for transactions,
/// whereas `StoreKit 2` uses `StoreKit.Product.Purchase`.
/// - Important: This configuration flag has been deprecated, and will be replaced by automatic remote configuration in the future.
/// However, apps using it should work correctly.
///
@available(*, deprecated, message: """
RevenueCat currently uses StoreKit 1 for purchases, as its stability in production scenarios has
proven to be more performant than StoreKit 2.
We're collecting more data on the best approach, but StoreKit 1 vs StoreKit 2 is an implementation detail
that you shouldn't need to care about.
Simply remove this method call to let RevenueCat decide for you which StoreKit implementation to use.
""")
@objc func with(storeKitVersion: Configuration.StoreKitVersion) -> Configuration.Builder {
self.storeKit2Setting = .init(version: storeKitVersion)
return self
}

/**
* Set `observerMode`.
* - Parameter observerMode: Set this to `true` if you have your own IAP implementation and want to use only
* RevenueCat's backend. Default is `false`.
*
* - Warning: This assumes your IAP implementation uses StoreKit 1.
* If you use StoreKit 2, use ``with(observerMode:storeKit2:)`` instead.
* If you use StoreKit 2, use ``with(observerMode:storeKitVersion:)`` instead.
*/
@available(*, deprecated, message: "", renamed: "with(observerMode:storeKit2:)")
@objc func with(observerMode: Bool) -> Configuration.Builder {
return self.with(observerMode: observerMode, storeKit2: false)
return self.with(observerMode: observerMode, storeKitVersion: .storeKit1)
}

}
Expand Down
9 changes: 9 additions & 0 deletions Sources/Misc/StoreKit2Setting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ extension StoreKit2Setting {
: .enabledOnlyForOptimizations
}

init(version: Configuration.StoreKitVersion) {
switch version {
case .storeKit1:
self = .enabledOnlyForOptimizations
case .storeKit2:
self = .enabledForCompatibleDevices
}
}

static let `default`: Self = .enabledOnlyForOptimizations

}
Expand Down
23 changes: 19 additions & 4 deletions Sources/Purchasing/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ import Foundation
*/
@objc(RCConfiguration) public final class Configuration: NSObject {

/// The StoreKit version that the SDK is setup with.
@objc(RCConfigurationStoreKitVersion)
public enum StoreKitVersion: Int {

// swiftlint:disable missing_docs
case storeKit1 = 1
case storeKit2 = 2
// swiftlint:enable missing_docs

}

static let storeKitRequestTimeoutDefault: TimeInterval = 30
static let networkTimeoutDefault: TimeInterval = 60

Expand Down Expand Up @@ -126,14 +137,18 @@ import Foundation
}

/**
* Set `observerMode` with a corresponding `StoreKit 2` setting.
* Set `observerMode` with a corresponding `StoreKit` implementation.
* - Parameter observerMode: Set this to `true` if you have your own IAP implementation and want to use only
* RevenueCat's backend. Default is `false`.
* - Parameter storeKit2: Set this to `true` if your own IAP implementation uses StoreKit 2. Default is `false`.
* - Parameter storeKitVersion: Set this to the StoreKit implementation your app uses for purchases.
* I.e.: if your app uses `StoreKit 1`, set it to ``Configuration/StoreKitVersion/storeKit1``
* and if your app uses `StoreKit 2`, set it to ``Configuration/StoreKitVersion/storeKit2``.
* Apps using `StoreKit 1` use `SKPaymentQueue` for transactions,
* whereas `StoreKit 2` uses `StoreKit.Product.Purchase`.
*/
@objc public func with(observerMode: Bool, storeKit2: Bool) -> Builder {
@objc public func with(observerMode: Bool, storeKitVersion: StoreKitVersion) -> Builder {
self.observerMode = observerMode
self.storeKit2Setting = .init(useStoreKit2IfAvailable: storeKit2)
self.storeKit2Setting = .init(version: storeKitVersion)
return self
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/Purchasing/Purchases/Purchases.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ public extension Purchases {
* - Returns: An instantiated ``Purchases`` object that has been set as a singleton.
*
* - Note: This assumes your IAP implementation uses StoreKit 1.
* If you use StoreKit 2, use ``Configuration/Builder/with(observerMode:storeKit2:)`` instead.
* If you use StoreKit 2, use ``Configuration/Builder/with(observerMode:storeKitVersion:)`` instead.
*/
@objc(configureWithAPIKey:appUserID:observerMode:)
@discardableResult static func configure(withAPIKey apiKey: String,
Expand All @@ -1150,7 +1150,7 @@ public extension Purchases {
with: Configuration
.builder(withAPIKey: apiKey)
.with(appUserID: appUserID)
.with(observerMode: observerMode, storeKit2: false)
.with(observerMode: observerMode, storeKitVersion: .storeKit1)
.build()
)
}
Expand Down
32 changes: 21 additions & 11 deletions Tests/APITesters/ObjCAPITester/ObjCAPITester/RCConfigurationAPI.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,32 @@ @implementation RCConfigurationAPI

+ (void)checkAPI {
RCConfigurationBuilder *builder = [RCConfiguration builderWithAPIKey:@""];
RCConfiguration *config __unused = [[[[[[[[[[[[builder withApiKey:@""]
withObserverMode:false]
withObserverMode:true storeKit2:true]
withUserDefaults:NSUserDefaults.standardUserDefaults]
withAppUserID:@""]
withAppUserID:nil]
withDangerousSettings:[[RCDangerousSettings alloc] init]]
withNetworkTimeout:1]
withStoreKit1Timeout: 1]
withPlatformInfo:[[RCPlatformInfo alloc] initWithFlavor:@"" version:@""]]
withUsesStoreKit2IfAvailable:false] build];
RCConfiguration *config __unused = [[[[[[[[[[[[[builder withApiKey:@""]
withObserverMode:false]
withObserverMode:true storeKitVersion:RCConfigurationStoreKitVersionStoreKit1]
withUserDefaults:NSUserDefaults.standardUserDefaults]
withAppUserID:@""]
withAppUserID:nil]
withDangerousSettings:[[RCDangerousSettings alloc] init]]
withNetworkTimeout:1]
withStoreKit1Timeout: 1]
withPlatformInfo:[[RCPlatformInfo alloc] initWithFlavor:@"" version:@""]]
withUsesStoreKit2IfAvailable:false]
withStoreKitVersion:RCConfigurationStoreKitVersionStoreKit2]
build];

if (@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *)) {
RCConfiguration *config __unused = [[builder
withEntitlementVerificationMode:RCEntitlementVerificationModeInformational] build];
}
}

+ (void)checkStoreKitVersion:(RCConfigurationStoreKitVersion)version {
switch (version) {
case RCConfigurationStoreKitVersionStoreKit1:
case RCConfigurationStoreKitVersionStoreKit2:
break;
}
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ func checkConfigurationAPI() {
.with(apiKey: "")
.with(appUserID: "")
.with(appUserID: nil)
.with(observerMode: false, storeKit2: true)
.with(observerMode: false, storeKitVersion: .storeKit1)
.with(observerMode: true, storeKitVersion: .storeKit2)
.with(userDefaults: UserDefaults.standard)
.with(dangerousSettings: DangerousSettings())
.with(dangerousSettings: DangerousSettings(autoSyncPurchases: true))
Expand All @@ -31,9 +32,19 @@ func checkConfigurationAPI() {
}
}

func checkStoreKitVersion(_ version: Configuration.StoreKitVersion) {
switch version {
case .storeKit1: break
case .storeKit2: break
@unknown default: break
}
}

@available(*, deprecated)
func checkDeprecatedConfiguration(_ builder: Configuration.Builder) {
_ = builder
.with(usesStoreKit2IfAvailable: false)
.with(storeKitVersion: .storeKit1)
.with(storeKitVersion: .storeKit2)
.with(observerMode: true)
}
8 changes: 8 additions & 0 deletions Tests/UnitTests/Misc/StoreKit2SettingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ class StoreKit2SettingTests: TestCase {
expect(StoreKit2Setting(useStoreKit2IfAvailable: false).usesStoreKit2IfAvailable) == false
}

func testInitWithStoreKit1() {
expect(StoreKit2Setting(version: .storeKit1)) == .enabledOnlyForOptimizations
}

func testInitWithStoreKit2() {
expect(StoreKit2Setting(version: .storeKit2)) == .enabledForCompatibleDevices
}

func testStoreKit2NotAvailableWhenDisabled() {
expect(StoreKit2Setting.disabled.shouldOnlyUseStoreKit2) == false
}
Expand Down
8 changes: 4 additions & 4 deletions Tests/UnitTests/Purchasing/ConfigurationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,18 @@ class ConfigurationTests: TestCase {
expect(configuration.storeKit2Setting) == .enabledOnlyForOptimizations
}

func testObserverModeWithStoreKit2Disabled() {
func testObserverModeWithStoreKit1() {
let configuration = Configuration.Builder(withAPIKey: "test")
.with(observerMode: true, storeKit2: false)
.with(observerMode: true, storeKitVersion: .storeKit1)
.build()

expect(configuration.observerMode) == true
expect(configuration.storeKit2Setting) == .enabledOnlyForOptimizations
}

func testObserverModeWithStoreKit2Enabled() {
func testObserverModeWithStoreKit2() {
let configuration = Configuration.Builder(withAPIKey: "test")
.with(observerMode: true, storeKit2: true)
.with(observerMode: true, storeKitVersion: .storeKit2)
.build()

expect(configuration.observerMode) == true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ class PurchasesConfiguringTests: BasePurchasesTests {
private static func create(observerMode: Bool) -> Purchases {
return Purchases.configure(
with: .init(withAPIKey: "")
.with(observerMode: observerMode, storeKit2: false)
.with(observerMode: observerMode, storeKitVersion: .storeKit1)
)
}

Expand Down

0 comments on commit d5d78b3

Please sign in to comment.