diff --git a/Sources/Purchasing/Purchases/Purchases.swift b/Sources/Purchasing/Purchases/Purchases.swift index 2996ad19d3..62eb15d8b2 100644 --- a/Sources/Purchasing/Purchases/Purchases.swift +++ b/Sources/Purchasing/Purchases/Purchases.swift @@ -1597,7 +1597,20 @@ extension Purchases: PurchasesOrchestratorDelegate { */ func readyForPromotedProduct(_ product: StoreProduct, purchase startPurchase: @escaping StartPurchaseBlock) { - self.delegate?.purchases?(self, readyForPromotedProduct: product, purchase: startPurchase) + + switch systemInfo.storeKitVersion { + 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. + 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 diff --git a/Tests/UnitTests/Purchasing/Purchases/PurchasesDeferredPurchasesTests.swift b/Tests/UnitTests/Purchasing/Purchases/PurchasesDeferredPurchasesTests.swift index ff2fc73790..1357143b14 100644 --- a/Tests/UnitTests/Purchasing/Purchases/PurchasesDeferredPurchasesTests.swift +++ b/Tests/UnitTests/Purchasing/Purchases/PurchasesDeferredPurchasesTests.swift @@ -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)