Create separate SPM library to enable custom entitlement computation (#2440)

Fixes SDK-3084

![screenshot_2023-04-25_at_10 02
44_480](https://user-images.githubusercontent.com/685609/234360670-bd2628a1-0684-490d-a9eb-33846a60f72a.png)

## Changes:

- Added new `ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION` compile time flag
- Hidden `configureInCustomEntitlementsModeWithApiKey` behind
`ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION`
- Added new `RevenueCat_CustomEntitlementComputation` SPM target and
library
- Added CircleCI job for `swift build --target
RevenueCat_CustomEntitlementComputation`
- Added new `SPMCustomEntitlementComputationInstallation` using the new
`configureInCustomEntitlementsComputationMode`
- Added CircleCI job for `SPMCustomEntitlementComputationInstallation`
- Added `FrameworkDisambiguation.swift` to avoid using `RevenueCat.`
disambiguation for files that
- Changed API testers to only use the new methods if
`ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION` is defined
- Updated `DangerousSettings` to not expose
`customEntitlementComputation` publicly. The only way to use that now
with `public` API is through
`Purchases.configureInCustomEntitlementsModeWithApiKey`
- Updated sample app to use new library
This commit is contained in:
NachoSoto authored and GitHub committed 2023-04-25 15:11:58 -07:00
1 parent 618ff121d2
commit 64c8638425
30 files changed
+998 -55

No files matched your search

+44
View File
@@ -168,6 +168,24 @@ commands:
working_directory: << parameters.directory >>
when: always
scan:
parameters:
directory:
type: string
steps:
- run:
name: Replace API key
command: bundle exec fastlane replace_api_key_integration_tests
- run:
name: Run tests
working_directory: << parameters.directory >>
command: bundle exec fastlane scan
- store_test_results:
path: fastlane/test_output
- store_artifacts:
path: fastlane/test_output/report.html
destination: test_report.html
scan-and-archive:
parameters:
directory:
@@ -269,6 +287,15 @@ jobs:
command: swift build -c release --target RevenueCat
no_output_timeout: 30m
spm-custom-entitlement-computation-build:
<<: *base-job
steps:
- checkout
- run:
name: SPM Custom Entitlement Computation Build
command: swift build --target RevenueCat_CustomEntitlementComputation
no_output_timeout: 30m
spm-receipt-parser:
<<: *base-job
steps:
@@ -551,6 +578,17 @@ jobs:
- scan-and-archive-all-platforms:
directory: Tests/InstallationTests/SPMInstallation/
installation-tests-custom-entitlement-computation-swift-package-manager:
<<: *base-job
steps:
- checkout
- trust-github-key
- update-spm-installation-commit
- install-dependencies:
directory: Tests/InstallationTests/SPMCustomEntitlementComputationInstallation/
- scan:
directory: Tests/InstallationTests/SPMCustomEntitlementComputationInstallation/
installation-tests-receipt-parser:
<<: *base-job
steps:
@@ -732,6 +770,8 @@ workflows:
xcode_version: '14.3.0'
- spm-release-build:
xcode_version: '14.3.0'
- spm-custom-entitlement-computation-build:
xcode_version: '14.3.0'
- spm-receipt-parser:
xcode_version: '14.3.0'
- run-test-ios-16:
@@ -775,6 +815,9 @@ workflows:
- installation-tests-swift-package-manager:
xcode_version: '14.3.0'
<<: *release-branches
- installation-tests-custom-entitlement-computation-swift-package-manager:
xcode_version: '14.3.0'
<<: *release-branches
- installation-tests-receipt-parser:
xcode_version: '14.1.0'
<<: *release-branches
@@ -790,6 +833,7 @@ workflows:
- release-checks
- installation-tests-cocoapods
- installation-tests-swift-package-manager
- installation-tests-custom-entitlement-computation-swift-package-manager
- installation-tests-carthage
- installation-tests-xcode-direct-integration
- installation-tests-receipt-parser
+1
View File
@@ -0,0 +1 @@
Sources
@@ -12,7 +12,7 @@
2D276F5A29F1C85800F51382 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2D276F5929F1C85800F51382 /* Assets.xcassets */; };
2D276F5D29F1C85800F51382 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2D276F5C29F1C85800F51382 /* Preview Assets.xcassets */; };
2DB0898929F30ABD00A4DAE7 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB0898829F30ABD00A4DAE7 /* Constants.swift */; };
2DB0899329F32C9F00A4DAE7 /* RevenueCat in Frameworks */ = {isa = PBXBuildFile; productRef = 2DB0899229F32C9F00A4DAE7 /* RevenueCat */; };
5714383029F86B4400CC2D44 /* RevenueCat_CustomEntitlementComputation in Frameworks */ = {isa = PBXBuildFile; productRef = 5714382F29F86B4400CC2D44 /* RevenueCat_CustomEntitlementComputation */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -30,7 +30,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2DB0899329F32C9F00A4DAE7 /* RevenueCat in Frameworks */,
5714383029F86B4400CC2D44 /* RevenueCat_CustomEntitlementComputation in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -99,7 +99,7 @@
);
name = testCustomEntitlementsComputation;
packageProductDependencies = (
2DB0899229F32C9F00A4DAE7 /* RevenueCat */,
5714382F29F86B4400CC2D44 /* RevenueCat_CustomEntitlementComputation */,
);
productName = testCustomEntitlementsComputation;
productReference = 2D276F5229F1C85700F51382 /* testCustomEntitlementsComputation.app */;
@@ -362,9 +362,9 @@
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
2DB0899229F32C9F00A4DAE7 /* RevenueCat */ = {
5714382F29F86B4400CC2D44 /* RevenueCat_CustomEntitlementComputation */ = {
isa = XCSwiftPackageProductDependency;
productName = RevenueCat;
productName = RevenueCat_CustomEntitlementComputation;
};
/* End XCSwiftPackageProductDependency section */
};
@@ -6,7 +6,7 @@
//
import SwiftUI
import RevenueCat
import RevenueCat_CustomEntitlementComputation
struct CustomerInfoStreamFires: Identifiable {
let customerInfo: CustomerInfo
+6
View File
@@ -27,6 +27,8 @@ let package = Package(
products: [
.library(name: "RevenueCat",
targets: ["RevenueCat"]),
.library(name: "RevenueCat_CustomEntitlementComputation",
targets: ["RevenueCat_CustomEntitlementComputation"]),
.library(name: "ReceiptParser",
targets: ["ReceiptParser"])
],
@@ -35,6 +37,10 @@ let package = Package(
.target(name: "RevenueCat",
path: "Sources",
exclude: ["Info.plist", "LocalReceiptParsing/ReceiptParser-only-files"]),
.target(name: "RevenueCat_CustomEntitlementComputation",
path: "CustomEntitlementComputation",
exclude: ["Info.plist", "LocalReceiptParsing/ReceiptParser-only-files"],
swiftSettings: [.define("ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION")]),
.target(name: "ReceiptParser",
path: "LocalReceiptParsing"),
.testTarget(name: "ReceiptParserTests", dependencies: ["ReceiptParser", "Nimble"])
+4
View File
@@ -366,6 +366,7 @@
57BB071628D282A4007F5DF0 /* CachingProductsManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57BB071528D282A4007F5DF0 /* CachingProductsManagerTests.swift */; };
57BD50AA27692B7500211D6D /* StoreKitError+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57BD50A927692B7500211D6D /* StoreKitError+Extensions.swift */; };
57BF87592967880C00424254 /* MockCachingTrialOrIntroPriceEligibilityChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57BF87582967880C00424254 /* MockCachingTrialOrIntroPriceEligibilityChecker.swift */; };
57C0BB6929F840BD00827807 /* FrameworkDisambiguation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57C0BB6829F840BD00827807 /* FrameworkDisambiguation.swift */; };
57C2931528BFEF4F0054EDFC /* PurchasesError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57C2931428BFEF4F0054EDFC /* PurchasesError.swift */; };
57C2932A28BFF89D0054EDFC /* ErrorMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E4A52028BD8F610095C793 /* ErrorMatcher.swift */; };
57C381B72791E593009E3940 /* StoreKit2TransactionListenerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57C381B62791E593009E3940 /* StoreKit2TransactionListenerTests.swift */; };
@@ -1018,6 +1019,7 @@
57BB071528D282A4007F5DF0 /* CachingProductsManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachingProductsManagerTests.swift; sourceTree = "<group>"; };
57BD50A927692B7500211D6D /* StoreKitError+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StoreKitError+Extensions.swift"; sourceTree = "<group>"; };
57BF87582967880C00424254 /* MockCachingTrialOrIntroPriceEligibilityChecker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockCachingTrialOrIntroPriceEligibilityChecker.swift; sourceTree = "<group>"; };
57C0BB6829F840BD00827807 /* FrameworkDisambiguation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameworkDisambiguation.swift; sourceTree = "<group>"; };
57C2931428BFEF4F0054EDFC /* PurchasesError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchasesError.swift; sourceTree = "<group>"; };
57C381B62791E593009E3940 /* StoreKit2TransactionListenerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreKit2TransactionListenerTests.swift; sourceTree = "<group>"; };
57C381D92796153D009E3940 /* SK1StoreProductDiscount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SK1StoreProductDiscount.swift; sourceTree = "<group>"; };
@@ -1905,6 +1907,7 @@
35E840C5270FB47C00899AE2 /* ManageSubscriptionsHelper.swift */,
578C5F2B28DB82DD00A56F02 /* PurchasesDiagnostics.swift */,
57F2C60B29784C11009EE527 /* SwiftVersionCheck.swift */,
57C0BB6829F840BD00827807 /* FrameworkDisambiguation.swift */,
);
path = Support;
sourceTree = "<group>";
@@ -3000,6 +3003,7 @@
B35042C426CDB79A00905B95 /* Purchases.swift in Sources */,
2D22BF6526F3CB31001AE2F9 /* FatalErrorUtil.swift in Sources */,
2D1015DE275A57FC0086173F /* SubscriptionPeriod.swift in Sources */,
57C0BB6929F840BD00827807 /* FrameworkDisambiguation.swift in Sources */,
B3B5FBBF269E081E00104A0C /* InMemoryCachedObject.swift in Sources */,
579B67F428C5326A0094F7E8 /* PaymentQueueWrapper.swift in Sources */,
B3DDB55926854865008CCF23 /* PurchaseOwnershipType.swift in Sources */,
@@ -108,7 +108,6 @@ Most features require configuring the SDK before using it.
- ``Purchases/setOnesignalID(_:)``
### Advanced Configuration
- ``Purchases/configureInCustomEntitlementsComputationMode(apiKey:appUserID:)``
- ``Purchases/finishTransactions``
- ``Purchases/invalidateCustomerInfoCache()``
- ``Purchases/forceUniversalAppStore``
@@ -58,9 +58,6 @@ Or browse our iOS sample apps:
- ``Purchases/configure(with:)-6oipy``
- ``PurchasesDiagnostics``
### Advanced Configuration
- ``Purchases/configureInCustomEntitlementsComputationMode(apiKey:appUserID:)``
### Displaying Products
- ``Offerings``
- ``Offering``
+8 -8
View File
@@ -36,14 +36,14 @@ struct Logger {
static var logHandler: VerboseLogHandler = Self.defaultLogHandler
static let defaultLogHandler: VerboseLogHandler = { level, message, file, functionName, line in
RevenueCat.defaultLogHandler(
framework: Self.frameworkDescription,
verbose: Logger.verbose,
level: level,
message: message,
file: file,
function: functionName,
line: line
RCDefaultLogHandler(
Self.frameworkDescription,
Logger.verbose,
level,
message,
file,
functionName,
line
)
}
@@ -150,7 +150,7 @@ extension Purchases {
forProductDiscount: discount,
product: product
)
} catch RevenueCat.ErrorCode.ineligibleError {
} catch RCErrorCode.ineligibleError {
return nil
} catch {
Logger.error(
+9 -1
View File
@@ -67,7 +67,15 @@ import Foundation
* If this is disabled, RevenueCat won't observe the StoreKit queue, and it will not sync any purchase
* automatically.
*/
@objc public convenience init(autoSyncPurchases: Bool = true, customEntitlementComputation: Bool = false) {
@objc public convenience init(autoSyncPurchases: Bool = true) {
self.init(autoSyncPurchases: autoSyncPurchases,
customEntitlementComputation: false)
}
/// - Note: this is `internal` only so the only `public` way to enable `customEntitlementComputation`
/// is through ``Purchases/configureInCustomEntitlementsComputationMode(apiKey:appUserID:)``.
@objc internal convenience init(autoSyncPurchases: Bool = true, customEntitlementComputation: Bool) {
self.init(autoSyncPurchases: autoSyncPurchases,
customEntitlementComputation: customEntitlementComputation,
internalSettings: .default)
+41 -31
View File
@@ -641,6 +641,8 @@ public extension Purchases {
return try await logOutAsync()
}
#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
///
/// Updates the current appUserID to a new one, without associating the two.
/// - Important: This method is **only available** in Custom Entitlements Computation mode.
@@ -657,6 +659,8 @@ public extension Purchases {
self.identityManager.switchUser(to: newAppUserID)
}
#endif
@objc func getOfferings(completion: @escaping (Offerings?, PublicError?) -> Void) {
self.getOfferings(fetchPolicy: .default, completion: completion)
}
@@ -990,6 +994,8 @@ public extension Purchases {
return Self.configure(with: builder.build())
}
#if !ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
/**
* Configures an instance of the Purchases SDK with a specified API key.
*
@@ -1032,6 +1038,40 @@ public extension Purchases {
Self.configure(withAPIKey: apiKey, appUserID: appUserID, observerMode: false)
}
/**
* Configures an instance of the Purchases SDK with a custom `UserDefaults`.
*
* Use this constructor if you want to
* sync status across a shared container, such as between a host app and an extension. The instance of the
* Purchases SDK will be set as a singleton.
* You should access the singleton instance using ``Purchases/shared``
*
* - Parameter apiKey: The API Key generated for your app from https://app.revenuecat.com/
*
* - Parameter appUserID: The unique app user id for this user. This user id will allow users to share their
* purchases and subscriptions across devices. Pass `nil` or an empty string if you want ``Purchases``
* to generate this for you.
*
* - Parameter observerMode: Set this to `true` if you have your own IAP implementation and want to use only
* RevenueCat's backend. Default is `false`.
*
* - Returns: An instantiated ``Purchases`` object that has been set as a singleton.
*/
@objc(configureWithAPIKey:appUserID:observerMode:)
@discardableResult static func configure(withAPIKey apiKey: String,
appUserID: String?,
observerMode: Bool) -> Purchases {
Self.configure(
with: Configuration
.builder(withAPIKey: apiKey)
.with(appUserID: appUserID)
.with(observerMode: observerMode)
.build()
)
}
#else
/**
* Configures an instance of the Purchases SDK with a specified API key and
* app user ID in Custom Entitlements Computation mode.
@@ -1075,37 +1115,7 @@ public extension Purchases {
.build())
}
/**
* Configures an instance of the Purchases SDK with a custom `UserDefaults`.
*
* Use this constructor if you want to
* sync status across a shared container, such as between a host app and an extension. The instance of the
* Purchases SDK will be set as a singleton.
* You should access the singleton instance using ``Purchases/shared``
*
* - Parameter apiKey: The API Key generated for your app from https://app.revenuecat.com/
*
* - Parameter appUserID: The unique app user id for this user. This user id will allow users to share their
* purchases and subscriptions across devices. Pass `nil` or an empty string if you want ``Purchases``
* to generate this for you.
*
* - Parameter observerMode: Set this to `true` if you have your own IAP implementation and want to use only
* RevenueCat's backend. Default is `false`.
*
* - Returns: An instantiated ``Purchases`` object that has been set as a singleton.
*/
@objc(configureWithAPIKey:appUserID:observerMode:)
@discardableResult static func configure(withAPIKey apiKey: String,
appUserID: String?,
observerMode: Bool) -> Purchases {
Self.configure(
with: Configuration
.builder(withAPIKey: apiKey)
.with(appUserID: appUserID)
.with(observerMode: observerMode)
.build()
)
}
#endif
// swiftlint:disable:next function_parameter_count
@discardableResult internal static func configure(
@@ -100,7 +100,7 @@ private extension SK2BeginRefundRequestHelper {
* to our `RefundRequestStatus` type and adding more descriptive error messages where needed.
*/
func mapSk2Result(from sk2Result: Result<StoreKit.Transaction.RefundRequestStatus, Error>) throws ->
RevenueCat.RefundRequestStatus {
RCRefundRequestStatus {
switch sk2Result {
case .success(let sk2Status):
guard let rcStatus = RefundRequestStatus.from(sk2RefundRequestStatus: sk2Status) else {
@@ -0,0 +1,26 @@
//
// Copyright RevenueCat Inc. All Rights Reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/MIT
//
// FrameworkDisambiguation.swift
//
// Created by Nacho Soto on 4/25/23.w
/**
Purpose: this file is needed because several parts of the SDK need to explicitily reference a type or value
from the `RevenueCat` target. However, we expose 2 variants of the framework from SPM:
`RevenueCat` and `RevenueCat_CustomEntitlementComputation` (see `Package.swift`).
Because of that, we can't simply do `RevenueCat.ErrorCode` for example, since the other variant
would need `RevenueCat_CustomEntitlementComputation.ErrorCode`.
To handle that, this exposes those types explicitly so they work regardless of the name of the framework.
*/
typealias RCRefundRequestStatus = RefundRequestStatus
typealias RCErrorCode = ErrorCode
let RCDefaultLogHandler = defaultLogHandler
@@ -66,8 +66,10 @@ BOOL isAnonymous;
dangerousSettings:[[RCDangerousSettings alloc] initWithAutoSyncPurchases:NO
customEntitlementComputation:NO]];
#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
[RCPurchases configureInCustomEntitlementsModeWithApiKey:@""
appUserID:@""];
#endif
[RCPurchases setLogHandler:^(RCLogLevel l, NSString *i) {}];
@@ -175,9 +177,12 @@ BOOL isAnonymous;
[p purchasePackage:pack withPromotionalOffer:pro completion:^(RCStoreTransaction *t, RCCustomerInfo *i, NSError *e, BOOL userCancelled) { }];
[p logIn:@"" completion:^(RCCustomerInfo *i, BOOL created, NSError *e) { }];
[p switchUserToNewAppUserID:@""];
[p logOutWithCompletion:^(RCCustomerInfo *i, NSError *e) { }];
#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
[p switchUserToNewAppUserID:@""];
#endif
[p.delegate purchases:p receivedUpdatedCustomerInfo:pi];
[p.delegate purchases:p
readyForPromotedProduct:storeProduct
@@ -17,11 +17,18 @@ func checkConfigurationAPI() {
.with(observerMode: false)
.with(userDefaults: UserDefaults.standard)
.with(dangerousSettings: DangerousSettings())
.with(dangerousSettings: DangerousSettings(autoSyncPurchases: true))
.with(networkTimeout: 1)
.with(storeKit1Timeout: 1)
.with(platformInfo: Purchases.PlatformInfo(flavor: "", version: ""))
// Trusted Entitlements: internal until ready to be made public.
// .with(entitlementVerificationMode: .informational)
.build()
#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
_ = DangerousSettings(autoSyncPurchases: false,
customEntitlementComputation: true)
#endif
print(configuration)
}
@@ -157,7 +157,10 @@ private func checkPurchasesPurchasingAPI(purchases: Purchases) {
private func checkIdentity(purchases: Purchases) {
purchases.logOut { (_: CustomerInfo?, _: Error?) in }
purchases.logIn("") { (_: CustomerInfo?, _: Bool, _: Error?) in }
#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
purchases.switchUser(to: "")
#endif
}
private func checkPurchasesSupportAPI(purchases: Purchases) {
@@ -260,7 +263,10 @@ private func checkConfigure() -> Purchases! {
Purchases.configure(withAPIKey: "", appUserID: "", observerMode: false)
Purchases.configure(withAPIKey: "", appUserID: nil, observerMode: true)
#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
Purchases.configureInCustomEntitlementsComputationMode(apiKey: "", appUserID: "")
#endif
return nil
}
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
@@ -0,0 +1,39 @@
//
// InstallationTests.swift
// InstallationTests
//
// Created by Nacho Soto on 4/25/23.
//
import XCTest
import RevenueCat_CustomEntitlementComputation
class InstallationTests: XCTestCase {
override func setUp() {
super.setUp()
Purchases.logLevel = .debug
let proxyURL = "REVENUECAT_PROXY_URL"
if proxyURL != "REVENUECAT_PROXY_URL", !proxyURL.isEmpty {
Purchases.proxyURL = URL(string: proxyURL)!
}
Purchases.configureInCustomEntitlementsComputationMode(apiKey: "REVENUECAT_API_KEY",
appUserID: "Integration Tests")
}
func testCanFetchCustomerInfo() async throws {
_ = try await Purchases.shared.customerInfo()
}
func testCanSwitchUser() throws {
let userID = "new_user_ID"
Purchases.shared.switchUser(to: userID)
XCTAssertEqual(Purchases.shared.appUserID, userID)
}
}
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,353 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
57C0BB7029F844B700827807 /* InstallationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57C0BB6B29F8449900827807 /* InstallationTests.swift */; };
57C0BB8829F8486700827807 /* RevenueCat_CustomEntitlementComputation in Frameworks */ = {isa = PBXBuildFile; productRef = 57C0BB8729F8486700827807 /* RevenueCat_CustomEntitlementComputation */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
2D1D5739278DC9B000359BB1 /* SPMInstallation.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SPMInstallation.entitlements; sourceTree = "<group>"; };
2D6C021F2549F5620039CB92 /* SPMInstallationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SPMInstallationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
57C0BB6B29F8449900827807 /* InstallationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstallationTests.swift; sourceTree = "<group>"; };
57C0BB8429F8482F00827807 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
2D6C021C2549F5620039CB92 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
57C0BB8829F8486700827807 /* RevenueCat_CustomEntitlementComputation in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2D6C01FB2549F5600039CB92 = {
isa = PBXGroup;
children = (
2D1D5739278DC9B000359BB1 /* SPMInstallation.entitlements */,
57C0BB6B29F8449900827807 /* InstallationTests.swift */,
57C0BB8429F8482F00827807 /* Info.plist */,
2D6C02052549F5600039CB92 /* Products */,
2D6C02682549F5D40039CB92 /* Frameworks */,
);
sourceTree = "<group>";
};
2D6C02052549F5600039CB92 /* Products */ = {
isa = PBXGroup;
children = (
2D6C021F2549F5620039CB92 /* SPMInstallationTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
2D6C02682549F5D40039CB92 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
2D6C021E2549F5620039CB92 /* SPMInstallationTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2D6C02362549F5620039CB92 /* Build configuration list for PBXNativeTarget "SPMInstallationTests" */;
buildPhases = (
2D6C021B2549F5620039CB92 /* Sources */,
2D6C021C2549F5620039CB92 /* Frameworks */,
2D6C021D2549F5620039CB92 /* Resources */,
);
buildRules = (
);
dependencies = (
57C0BB8629F8486300827807 /* PBXTargetDependency */,
);
name = SPMInstallationTests;
packageProductDependencies = (
57C0BB8729F8486700827807 /* RevenueCat_CustomEntitlementComputation */,
);
productName = SPMInstallationTests;
productReference = 2D6C021F2549F5620039CB92 /* SPMInstallationTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
2D6C01FC2549F5600039CB92 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1430;
LastUpgradeCheck = 1210;
TargetAttributes = {
2D6C021E2549F5620039CB92 = {
CreatedOnToolsVersion = 12.1;
LastSwiftMigration = 1210;
};
};
};
buildConfigurationList = 2D6C01FF2549F5600039CB92 /* Build configuration list for PBXProject "SPMInstallation" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 2D6C01FB2549F5600039CB92;
packageReferences = (
57C0BB6529F83F3900827807 /* XCRemoteSwiftPackageReference "purchases-ios" */,
);
productRefGroup = 2D6C02052549F5600039CB92 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
2D6C021E2549F5620039CB92 /* SPMInstallationTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
2D6C021D2549F5620039CB92 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
2D6C021B2549F5620039CB92 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
57C0BB7029F844B700827807 /* InstallationTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
57C0BB8629F8486300827807 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
productRef = 57C0BB8529F8486300827807 /* RevenueCat_CustomEntitlementComputation */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
2D6C02312549F5620039CB92 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
2D6C02322549F5620039CB92 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
2D6C02372549F5620039CB92 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 8SXR2327BM;
INFOPLIST_FILE = Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.2;
OTHER_SWIFT_FLAGS = "-DSPM_INSTALLATION";
PRODUCT_BUNDLE_IDENTIFIER = com.revenuecat.SPMIntegrationTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
2D6C02382549F5620039CB92 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 8SXR2327BM;
INFOPLIST_FILE = Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.2;
OTHER_SWIFT_FLAGS = "-DSPM_INSTALLATION";
PRODUCT_BUNDLE_IDENTIFIER = com.revenuecat.SPMIntegrationTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2D6C01FF2549F5600039CB92 /* Build configuration list for PBXProject "SPMInstallation" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2D6C02312549F5620039CB92 /* Debug */,
2D6C02322549F5620039CB92 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2D6C02362549F5620039CB92 /* Build configuration list for PBXNativeTarget "SPMInstallationTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2D6C02372549F5620039CB92 /* Debug */,
2D6C02382549F5620039CB92 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
57C0BB6529F83F3900827807 /* XCRemoteSwiftPackageReference "purchases-ios" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/RevenueCat/purchases-ios";
requirement = {
branch = main;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
57C0BB8529F8486300827807 /* RevenueCat_CustomEntitlementComputation */ = {
isa = XCSwiftPackageProductDependency;
package = 57C0BB6529F83F3900827807 /* XCRemoteSwiftPackageReference "purchases-ios" */;
productName = RevenueCat_CustomEntitlementComputation;
};
57C0BB8729F8486700827807 /* RevenueCat_CustomEntitlementComputation */ = {
isa = XCSwiftPackageProductDependency;
package = 57C0BB6529F83F3900827807 /* XCRemoteSwiftPackageReference "purchases-ios" */;
productName = RevenueCat_CustomEntitlementComputation;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 2D6C01FC2549F5600039CB92 /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1220"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2D6C021E2549F5620039CB92"
BuildableName = "SPMInstallationTests.xctest"
BlueprintName = "SPMInstallationTests"
ReferencedContainer = "container:SPMInstallation.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57C0BB7529F847B600827807"
BuildableName = "SPMInstallation.app"
BlueprintName = "SPMInstallation"
ReferencedContainer = "container:SPMInstallation.xcodeproj">
</BuildableReference>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1 @@
import("../../../../fastlane/Fastfile")
@@ -0,0 +1,8 @@
git_url(ENV["CERTS_REPO_URL"])
storage_mode("git")
type("development")
app_identifier(["com.revenuecat.SPMIntegration"])
username(ENV["FASTLANE_USER"])
@@ -0,0 +1,267 @@
fastlane documentation
----
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```sh
xcode-select --install
```
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
# Available Actions
### check_pods
```sh
[bundle exec] fastlane check_pods
```
----
## iOS
### ios bump
```sh
[bundle exec] fastlane ios bump
```
Bump version, update swift header, edit changelog, and create pull request
### ios automatic_bump
```sh
[bundle exec] fastlane ios automatic_bump
```
Automatically bumps version, update swift header, edit changelog, and create pull request
### ios github_release
```sh
[bundle exec] fastlane ios github_release
```
Make github release
### ios prepare_next_version
```sh
[bundle exec] fastlane ios prepare_next_version
```
Creates PR changing version to next minor adding a -SNAPSHOT suffix
### ios setup_dev
```sh
[bundle exec] fastlane ios setup_dev
```
Setup development environment
### ios test_ios
```sh
[bundle exec] fastlane ios test_ios
```
Runs all the iOS tests
### ios test_tvos
```sh
[bundle exec] fastlane ios test_tvos
```
Runs all the tvOS tests
### ios test_watchos
```sh
[bundle exec] fastlane ios test_watchos
```
Runs all the watchOS tests
### ios release_checks
```sh
[bundle exec] fastlane ios release_checks
```
Release checks
### ios build_tv_watch_mac
```sh
[bundle exec] fastlane ios build_tv_watch_mac
```
build tvOS, watchOS, macOS
### ios build_mac
```sh
[bundle exec] fastlane ios build_mac
```
macOS build
### ios carthage_archive
```sh
[bundle exec] fastlane ios carthage_archive
```
Run the carthage archive steps to prepare for carthage distribution
### ios archive
```sh
[bundle exec] fastlane ios archive
```
archive
### ios archive_all_platforms
```sh
[bundle exec] fastlane ios archive_all_platforms
```
archive all platforms
### ios build_swift_api_tester
```sh
[bundle exec] fastlane ios build_swift_api_tester
```
build Swift API tester
### ios build_objc_api_tester
```sh
[bundle exec] fastlane ios build_objc_api_tester
```
build ObjC API tester
### ios replace_api_key_integration_tests
```sh
[bundle exec] fastlane ios replace_api_key_integration_tests
```
replace API KEY for installation and integration tests
### ios release
```sh
[bundle exec] fastlane ios release
```
Create Carthage archive, export XCFramework, and create GitHub release
### ios push_pods
```sh
[bundle exec] fastlane ios push_pods
```
Release to CocoaPods
### ios tag_current_branch
```sh
[bundle exec] fastlane ios tag_current_branch
```
Tag current branch with current version number
### ios compile_autogenerated_header
```sh
[bundle exec] fastlane ios compile_autogenerated_header
```
Creates RevenueCat-Swift.h for a new release
### ios export_xcframework
```sh
[bundle exec] fastlane ios export_xcframework
```
Export XCFramework
### ios backend_integration_tests
```sh
[bundle exec] fastlane ios backend_integration_tests
```
Run BackendIntegrationTests
### ios v3_loadshedder_integration_tests
```sh
[bundle exec] fastlane ios v3_loadshedder_integration_tests
```
Run LoadShedder tests
### ios update_swift_package_commit
```sh
[bundle exec] fastlane ios update_swift_package_commit
```
Update swift package commit
### ios preview_docs
```sh
[bundle exec] fastlane ios preview_docs
```
Preview docs
### ios generate_docs
```sh
[bundle exec] fastlane ios generate_docs
```
Generate docs
### ios deploy_purchase_tester
```sh
[bundle exec] fastlane ios deploy_purchase_tester
```
Build and deploy PurchaseTesterSwiftUI
### ios sandbox_testers
```sh
[bundle exec] fastlane ios sandbox_testers
```
Create or delete sandbox testers
----
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
@@ -0,0 +1,3 @@
# The scheme is only setup for testing, not building
# This makes it so that the `xcodebuild` command is only `test` and not `build test`, which would fail
skip_build(true)
@@ -100,6 +100,8 @@ class PurchasesLogInTests: BasePurchasesTests {
// MARK: - Switch user
#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
func testSwitchUserWontDoAnythingIfNotOnCustomEntitlementComputationMode() {
self.systemInfo = MockSystemInfo(finishTransactions: true, customEntitlementsComputation: false)
Purchases.clearSingleton()
@@ -121,6 +123,8 @@ class PurchasesLogInTests: BasePurchasesTests {
expect(self.identityManager.invokedSwitchUserParametersList) == ["test-user-id"]
}
#endif
// MARK: - Update offerings cache
func testLogInUpdatesOfferingsCache() throws {
+5 -2
View File
@@ -245,7 +245,8 @@ platform :ios do
new_text: ENV["REVENUECAT_API_KEY"],
paths_of_files_to_update: [
'./Tests/BackendIntegrationTests/Constants.swift',
'./Tests/InstallationTests/CommonFiles/RCInstallationRunner.m'
'./Tests/InstallationTests/CommonFiles/RCInstallationRunner.m',
'./Tests/InstallationTests/SPMCustomEntitlementComputationInstallation/InstallationTests.swift'
]
)
replace_text_in_files(
@@ -262,7 +263,8 @@ platform :ios do
new_text: ENV["REVENUECAT_PROXY_URL"].to_s,
paths_of_files_to_update: [
'./Tests/BackendIntegrationTests/Constants.swift',
'./Tests/InstallationTests/CommonFiles/RCInstallationRunner.m'
'./Tests/InstallationTests/CommonFiles/RCInstallationRunner.m',
'./Tests/InstallationTests/SPMCustomEntitlementComputationInstallation/InstallationTests.swift'
],
allow_empty: true
)
@@ -407,6 +409,7 @@ platform :ios do
lane :update_swift_package_commit do
project_file_locations = [
'./Tests/InstallationTests/SPMInstallation/SPMInstallation.xcodeproj/project.pbxproj',
'./Tests/InstallationTests/SPMCustomEntitlementComputationInstallation/SPMInstallation.xcodeproj/project.pbxproj',
'./Tests/InstallationTests/ReceiptParserInstallation/ReceiptParserInstallation.xcodeproj/project.pbxproj',
'./Examples/MagicWeather/MagicWeather.xcodeproj/project.pbxproj'
]