Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always call readyForPromotedProduct on main thread/actor #4613

Merged
merged 9 commits into from
Feb 3, 2025
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,7 @@ workflows:
- not: << pipeline.parameters.generate_revenuecatui_snapshots >>
jobs:
- lint
- run-test-ios-13
- run-test-ios-17
- run-test-ios-18
- pod-lib-lint
Expand Down
16 changes: 15 additions & 1 deletion Sources/Purchasing/Purchases/Purchases.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,21 @@ extension Purchases: PurchasesOrchestratorDelegate {
*/
func readyForPromotedProduct(_ product: StoreProduct,
purchase startPurchase: @escaping StartPurchaseBlock) {
self.delegate?.purchases?(self, readyForPromotedProduct: product, purchase: startPurchase)

switch self.systemInfo.storeKitVersion.effectiveVersion {
case .storeKit1:
// Calling the delegate method on the main actor causes test failures on iOS 14-16, so instead
// we dispatch to the main thread, which doesn't cause the failures.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i think this is good practice anyway, specially if we're calling on the main actor in sk2

OperationDispatcher.default.dispatchOnMainThread {
self.delegate?.purchases?(self, readyForPromotedProduct: product, purchase: startPurchase)
}
case .storeKit2:
// Ensure that the delegate method is called on the main actor for StoreKit 2.
OperationDispatcher.default.dispatchOnMainActor {
self.delegate?.purchases?(self, readyForPromotedProduct: product, purchase: startPurchase)
}
}

}

#if os(iOS) || targetEnvironment(macCatalyst) || VISION_OS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ class PurchaseDeferredPurchasesSK2Tests: BasePurchasesTests {
for: self.product
)

waitUntil { completed in
if self.purchasesDelegate.makeDeferredPurchase != nil {
completed()
}
}

expect(self.purchasesDelegate.makeDeferredPurchase).toNot(beNil())

expect(self.purchasesDelegate.promoProduct) == StoreProduct(sk1Product: self.product)
Expand Down