diff --git a/RevenueCat.xcodeproj/project.pbxproj b/RevenueCat.xcodeproj/project.pbxproj index 803bdf800c..d892416d84 100644 --- a/RevenueCat.xcodeproj/project.pbxproj +++ b/RevenueCat.xcodeproj/project.pbxproj @@ -2701,6 +2701,7 @@ 887A61342C1D168B00E1A461 /* SnapshotTesting+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SnapshotTesting+Extensions.swift"; sourceTree = ""; }; 887A61352C1D168B00E1A461 /* TestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCase.swift; sourceTree = ""; }; 887A61372C1D168B00E1A461 /* PurchaseHandlerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PurchaseHandlerTests.swift; sourceTree = ""; }; + 45010544C32C2A21A2F323D7 /* OnWebCheckoutOpenedModifierTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnWebCheckoutOpenedModifierTests.swift; sourceTree = ""; }; B10A136C03A9FF34FB805EFA /* ExitOfferPresenterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExitOfferPresenterTests.swift; sourceTree = ""; }; 887A620F2C1D168B00E1A461 /* OtherPaywallViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OtherPaywallViewTests.swift; sourceTree = ""; }; 887A62102C1D168B00E1A461 /* PaywallViewDynamicTypeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaywallViewDynamicTypeTests.swift; sourceTree = ""; }; @@ -5873,6 +5874,7 @@ 57F4B2C12F8E10A600BB46C9 /* ExitOfferHelperTests.swift */, 16E146B42E99FF640089B609 /* MockStoreTransaction.swift */, 887A61372C1D168B00E1A461 /* PurchaseHandlerTests.swift */, + 45010544C32C2A21A2F323D7 /* OnWebCheckoutOpenedModifierTests.swift */, B10A136C03A9FF34FB805EFA /* ExitOfferPresenterTests.swift */, 7AA86A1D9F5AE92988B20230 /* WorkflowContextTests.swift */, ECEA10EF63BC10F9BE6DB9F5 /* WorkflowPreviewTests.swift */, diff --git a/RevenueCatUI/PaywallView.swift b/RevenueCatUI/PaywallView.swift index 6928d5d55e..97ef9a1330 100644 --- a/RevenueCatUI/PaywallView.swift +++ b/RevenueCatUI/PaywallView.swift @@ -561,6 +561,8 @@ struct LoadedOfferingPaywallView: View { value: self.purchaseHandler.purchaseError as NSError?) .preference(key: RestoreErrorPreferenceKey.self, value: self.purchaseHandler.restoreError as NSError?) + .preference(key: WebCheckoutOpenedPreferenceKey.self, + value: self.purchaseHandler.webCheckoutOpened) } @ViewBuilder diff --git a/RevenueCatUI/Purchasing/PurchaseHandler.swift b/RevenueCatUI/Purchasing/PurchaseHandler.swift index 53aafdc908..84df52b5ff 100644 --- a/RevenueCatUI/Purchasing/PurchaseHandler.swift +++ b/RevenueCatUI/Purchasing/PurchaseHandler.swift @@ -111,6 +111,11 @@ final class PurchaseHandler: ObservableObject { @Published fileprivate(set) var consecutiveCancellationRequestID: UUID? + /// Set to a new UUID each time the user taps a web checkout CTA, propagated via + /// ``WebCheckoutOpenedPreferenceKey``. + @Published + fileprivate(set) var webCheckoutOpened: UUID? + /// Whether a purchase was successfully completed in the current session. /// Convenience property for checking if we should skip exit offers. var hasPurchasedInSession: Bool { @@ -258,6 +263,7 @@ final class PurchaseHandler: ObservableObject { self.consecutiveCancellationRequestID = nil self.purchaseResult = nil self.restoredCustomerInfo = nil + self.deferredClearWebCheckoutOpened() self.activePaywallSessionID = nil } @@ -856,6 +862,12 @@ extension PurchaseHandler { self.restoredCustomerInfo = .init(customerInfo: customerInfo, success: success) } + /// Sets a new UUID on ``webCheckoutOpened`` so ``WebCheckoutOpenedPreferenceKey`` fires. + @MainActor + func signalWebCheckoutOpened() { + self.webCheckoutOpened = UUID() + } + func trackPaywallImpression(_ eventData: PaywallEvent.Data) { self.activePaywallSessionID = eventData.sessionIdentifier self.paywallEventTracker.trackPaywallImpression(eventData) @@ -868,6 +880,24 @@ extension PurchaseHandler { self.activePaywallSessionID = nil } + /// Clears a pending web checkout signal without a full session reset, for when an exit offer is + /// about to reuse this same `PurchaseHandler`. Must run synchronously, unlike + /// `deferredClearWebCheckoutOpened`: the exit offer's paywall mounts in this same step, and a + /// deferred clear would let its brand new `onWebCheckoutOpened` observer see the stale signal as + /// its own fresh one. + @MainActor + func clearWebCheckoutOpened() { + self.webCheckoutOpened = nil + } + + /// Deferred by a tick so a signal set earlier in the same synchronous step (e.g. right before a + /// dismiss) still reaches its SwiftUI render pass before being cleared. + private func deferredClearWebCheckoutOpened() { + DispatchQueue.main.async { [weak self] in + self?.webCheckoutOpened = nil + } + } + func componentInteractionLogger(sessionID: PaywallEvent.SessionID) -> ComponentInteractionLogger { return self.paywallEventTracker.componentInteractionLogger(sessionID: sessionID) } @@ -1191,6 +1221,17 @@ struct RestoreErrorPreferenceKey: PreferenceKey { } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +struct WebCheckoutOpenedPreferenceKey: PreferenceKey { + + static var defaultValue: UUID? + + static func reduce(value: inout UUID?, nextValue: () -> UUID?) { + value = nextValue() + } + +} + // MARK: Environment keys /// `EnvironmentKey` for storing closure triggered when paywall should be dismissed. diff --git a/RevenueCatUI/Templates/V2/Components/Button/ButtonComponentView.swift b/RevenueCatUI/Templates/V2/Components/Button/ButtonComponentView.swift index 1c52693163..9fc99ee385 100644 --- a/RevenueCatUI/Templates/V2/Components/Button/ButtonComponentView.swift +++ b/RevenueCatUI/Templates/V2/Components/Button/ButtonComponentView.swift @@ -276,19 +276,14 @@ struct ButtonComponentView: View { private func openWebPaywallLink(url: URL, method: PaywallComponent.ButtonComponent.URLMethod) { self.purchaseHandler.invalidateCustomerInfoCache() -#if os(watchOS) - // watchOS doesn't support openURL with a completion handler, so we're just opening the URL. - openURL(url) -#else - openURL(url) { success in - if success { - Logger.debug(Strings.successfully_opened_url_external_browser(url.absoluteString)) - } else { - Logger.error(Strings.failed_to_open_url_external_browser(url.absoluteString)) - } + Browser.navigateTo(url: url, + method: method, + openURL: self.openURL, + inAppBrowserURL: self.$inAppBrowserURL) { opened in + guard opened else { return } + self.purchaseHandler.signalWebCheckoutOpened() + onDismiss() } -#endif - onDismiss() } } diff --git a/RevenueCatUI/Templates/V2/Components/Packages/PurchaseButton/PurchaseButtonComponentView.swift b/RevenueCatUI/Templates/V2/Components/Packages/PurchaseButton/PurchaseButtonComponentView.swift index 74795d0aa4..e76ff7d73e 100644 --- a/RevenueCatUI/Templates/V2/Components/Packages/PurchaseButton/PurchaseButtonComponentView.swift +++ b/RevenueCatUI/Templates/V2/Components/Packages/PurchaseButton/PurchaseButtonComponentView.swift @@ -189,10 +189,14 @@ struct PurchaseButtonComponentView: View { Browser.navigateTo(url: url, method: method, openURL: self.openURL, - inAppBrowserURL: self.$inAppBrowserURL) + inAppBrowserURL: self.$inAppBrowserURL) { opened in + guard opened else { return } - if launchWebCheckout.autoDismiss { - self.onDismiss() + self.purchaseHandler.signalWebCheckoutOpened() + + if launchWebCheckout.autoDismiss { + self.onDismiss() + } } } diff --git a/RevenueCatUI/Templates/V2/PaywallsV2View.swift b/RevenueCatUI/Templates/V2/PaywallsV2View.swift index a60f9f1f10..f492b699d9 100644 --- a/RevenueCatUI/Templates/V2/PaywallsV2View.swift +++ b/RevenueCatUI/Templates/V2/PaywallsV2View.swift @@ -386,6 +386,8 @@ struct PaywallsV2View: View { value: self.purchaseHandler.purchaseError as NSError?) .preference(key: RestoreErrorPreferenceKey.self, value: self.purchaseHandler.restoreError as NSError?) + .preference(key: WebCheckoutOpenedPreferenceKey.self, + value: self.purchaseHandler.webCheckoutOpened) .disabled(self.purchaseHandler.actionInProgress) .onDisappear { // Standalone closes on disappear. A workflow page closes here only if it is still the diff --git a/RevenueCatUI/Templates/V2/ViewHelpers/NavigatetoURL.swift b/RevenueCatUI/Templates/V2/ViewHelpers/NavigatetoURL.swift index 9d3e1a4d4d..c09e8d608f 100644 --- a/RevenueCatUI/Templates/V2/ViewHelpers/NavigatetoURL.swift +++ b/RevenueCatUI/Templates/V2/ViewHelpers/NavigatetoURL.swift @@ -17,11 +17,13 @@ import SwiftUI @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) enum Browser { + /// - Parameter completion: whether the URL actually opened. Not called for `.unknown`. static func navigateTo( url: URL, method: PaywallComponent.ButtonComponent.URLMethod, openURL: OpenURLAction, - inAppBrowserURL: Binding + inAppBrowserURL: Binding, + completion: ((Bool) -> Void)? = nil ) { switch method { case .inAppBrowser: @@ -34,14 +36,17 @@ enum Browser { } else { Logger.error(Strings.failed_to_open_url_external_browser(url.absoluteString)) } + completion?(success) } #else inAppBrowserURL.wrappedValue = url + completion?(true) #endif case .externalBrowser: #if os(watchOS) // watchOS doesn't support openURL with a completion handler, so we're just opening the URL. openURL(url) + completion?(true) #else openURL(url) { success in if success { @@ -49,12 +54,14 @@ enum Browser { } else { Logger.error(Strings.failed_to_open_url_external_browser(url.absoluteString)) } + completion?(success) } #endif case .deepLink: #if os(watchOS) // watchOS doesn't support openURL with a completion handler, so we're just opening the URL. openURL(url) + completion?(true) #else openURL(url) { success in if success { @@ -62,10 +69,11 @@ enum Browser { } else { Logger.error(Strings.failed_to_open_url_deep_link(url.absoluteString)) } + completion?(success) } #endif case .unknown: - break + completion?(false) } } diff --git a/RevenueCatUI/UIKit/PaywallViewController.swift b/RevenueCatUI/UIKit/PaywallViewController.swift index 49312a8606..d2b4011be7 100644 --- a/RevenueCatUI/UIKit/PaywallViewController.swift +++ b/RevenueCatUI/UIKit/PaywallViewController.swift @@ -725,6 +725,10 @@ public protocol PaywallViewControllerDelegate: AnyObject { @objc(paywallViewControllerDidCancelPurchase:) optional func paywallViewControllerDidCancelPurchase(_ controller: PaywallViewController) + /// Notifies that the user tapped a web checkout CTA and left the app to complete payment externally. + @objc(paywallViewControllerDidOpenWebCheckout:) + optional func paywallViewControllerDidOpenWebCheckout(_ controller: PaywallViewController) + /// Notifies that the purchase operation has failed in a ``PaywallViewController``. @objc(paywallViewController:didFailPurchasingWithError:) optional func paywallViewController(_ controller: PaywallViewController, @@ -825,6 +829,10 @@ private extension PaywallViewController { guard let self else { return } self.delegate?.paywallViewControllerDidCancelPurchase?(self) }, + webCheckoutOpened: { [weak self] in + guard let self else { return } + self.delegate?.paywallViewControllerDidOpenWebCheckout?(self) + }, restoreCompleted: { [weak self] customerInfo in guard let self else { return } self.delegate?.paywallViewController?(self, didFinishRestoringWith: customerInfo) @@ -956,6 +964,7 @@ private struct PaywallContainerView: View { let purchaseStarted: PurchaseOfPackageStartedHandler let purchaseCompleted: PurchaseCompletedHandler let purchaseCancelled: PurchaseCancelledHandler + let webCheckoutOpened: WebCheckoutOpenedHandler let restoreCompleted: PurchaseOrRestoreCompletedHandler let purchaseFailure: PurchaseFailureHandler let restoreStarted: RestoreStartedHandler @@ -976,6 +985,7 @@ private struct PaywallContainerView: View { .onPurchaseStarted(self.purchaseStarted) .onPurchaseCompleted(self.purchaseCompleted) .onPurchaseCancelled(self.purchaseCancelled) + .onWebCheckoutOpened(self.webCheckoutOpened) .onPurchaseFailure(self.purchaseFailure) .onRestoreStarted(self.restoreStarted) .onRestoreCompleted(self.restoreCompleted) diff --git a/RevenueCatUI/View+PresentPaywall.swift b/RevenueCatUI/View+PresentPaywall.swift index e49e4bfe84..ddc9a0331f 100644 --- a/RevenueCatUI/View+PresentPaywall.swift +++ b/RevenueCatUI/View+PresentPaywall.swift @@ -105,7 +105,8 @@ extension View { restoreCompleted: PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: PurchaseFailureHandler? = nil, restoreFailure: PurchaseFailureHandler? = nil, - onDismiss: (() -> Void)? = nil + onDismiss: (() -> Void)? = nil, + webCheckoutOpened: WebCheckoutOpenedHandler? = nil ) -> some View { return self.presentPaywallIfNeeded( requiredEntitlementIdentifier: requiredEntitlementIdentifier, @@ -121,7 +122,8 @@ extension View { restoreCompleted: restoreCompleted, purchaseFailure: purchaseFailure, restoreFailure: restoreFailure, - onDismiss: onDismiss + onDismiss: onDismiss, + webCheckoutOpened: webCheckoutOpened ) } @@ -159,7 +161,8 @@ extension View { restoreCompleted: PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: PurchaseFailureHandler? = nil, restoreFailure: PurchaseFailureHandler? = nil, - onDismiss: (() -> Void)? = nil + onDismiss: (() -> Void)? = nil, + webCheckoutOpened: WebCheckoutOpenedHandler? = nil ) -> some View { return self.presentPaywallIfNeeded( offering: offering, @@ -179,7 +182,8 @@ extension View { restoreCompleted: restoreCompleted, purchaseFailure: purchaseFailure, restoreFailure: restoreFailure, - onDismiss: onDismiss + onDismiss: onDismiss, + webCheckoutOpened: webCheckoutOpened ) } @@ -238,7 +242,8 @@ extension View { restoreCompleted: PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: PurchaseFailureHandler? = nil, restoreFailure: PurchaseFailureHandler? = nil, - onDismiss: (() -> Void)? = nil + onDismiss: (() -> Void)? = nil, + webCheckoutOpened: WebCheckoutOpenedHandler? = nil ) -> some View { return self.presentPaywallIfNeeded( offering: offering, @@ -256,6 +261,7 @@ extension View { purchaseFailure: purchaseFailure, restoreFailure: restoreFailure, onDismiss: onDismiss, + webCheckoutOpened: webCheckoutOpened, customerInfoFetcher: { guard Purchases.isConfigured else { throw PaywallError.purchasesNotConfigured @@ -317,7 +323,8 @@ extension View { restoreCompleted: PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: PurchaseFailureHandler? = nil, restoreFailure: PurchaseFailureHandler? = nil, - onDismiss: (() -> Void)? = nil + onDismiss: (() -> Void)? = nil, + webCheckoutOpened: WebCheckoutOpenedHandler? = nil ) -> some View { return self.presentPaywallIfNeeded( offering: offering, @@ -333,6 +340,7 @@ extension View { purchaseFailure: purchaseFailure, restoreFailure: restoreFailure, onDismiss: onDismiss, + webCheckoutOpened: webCheckoutOpened, customerInfoFetcher: { guard Purchases.isConfigured else { throw PaywallError.purchasesNotConfigured @@ -360,6 +368,7 @@ extension View { purchaseFailure: PurchaseFailureHandler? = nil, restoreFailure: PurchaseFailureHandler? = nil, onDismiss: (() -> Void)? = nil, + webCheckoutOpened: WebCheckoutOpenedHandler? = nil, customerInfoFetcher: @escaping CustomerInfoFetcher ) -> some View { return self @@ -375,6 +384,7 @@ extension View { restoreStarted: restoreStarted, restoreFailure: restoreFailure, onDismiss: onDismiss, + webCheckoutOpened: webCheckoutOpened, content: .optionalOffering(offering), fontProvider: fonts, customerInfoFetcher: customerInfoFetcher, @@ -420,6 +430,8 @@ extension View { /// - purchaseFailure: Called when a purchase fails. /// - restoreFailure: Called when a restore fails. /// - onDismiss: Called when the paywall (and any exit offer) is fully dismissed. + /// - webCheckoutOpened: Called when the user taps a web checkout CTA and leaves the app to + /// complete payment externally. /// /// ### Related Articles /// [Documentation](https://rev.cat/paywalls) @@ -435,7 +447,8 @@ extension View { restoreCompleted: PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: PurchaseFailureHandler? = nil, restoreFailure: PurchaseFailureHandler? = nil, - onDismiss: (() -> Void)? = nil + onDismiss: (() -> Void)? = nil, + webCheckoutOpened: WebCheckoutOpenedHandler? = nil ) -> some View { return self.modifier(PresentingPaywallBindingModifier( offering: offering, @@ -449,7 +462,8 @@ extension View { restoreCompleted: restoreCompleted, purchaseFailure: purchaseFailure, restoreFailure: restoreFailure, - onDismiss: onDismiss + onDismiss: onDismiss, + webCheckoutOpened: webCheckoutOpened )) } @@ -478,6 +492,7 @@ private struct PresentingPaywallModifier: ViewModifier { var restoreStarted: RestoreStartedHandler? var restoreFailure: PurchaseFailureHandler? var onDismiss: (() -> Void)? + var webCheckoutOpened: WebCheckoutOpenedHandler? var content: PaywallViewConfiguration.Content var fontProvider: PaywallFontProvider @@ -497,6 +512,7 @@ private struct PresentingPaywallModifier: ViewModifier { restoreStarted: RestoreStartedHandler?, restoreFailure: PurchaseFailureHandler?, onDismiss: (() -> Void)?, + webCheckoutOpened: WebCheckoutOpenedHandler?, content: PaywallViewConfiguration.Content, fontProvider: PaywallFontProvider, customerInfoFetcher: @escaping View.CustomerInfoFetcher, @@ -513,6 +529,7 @@ private struct PresentingPaywallModifier: ViewModifier { self.purchaseFailure = purchaseFailure self.restoreFailure = restoreFailure self.onDismiss = onDismiss + self.webCheckoutOpened = webCheckoutOpened self.content = content self.fontProvider = fontProvider self.customerInfoFetcher = customerInfoFetcher @@ -659,6 +676,9 @@ private struct PresentingPaywallModifier: ViewModifier { .onRestoreFailure { self.restoreFailure?($0) } + .onWebCheckoutOpened { + self.webCheckoutOpened?() + } .interactiveDismissDisabled(self.purchaseHandler.actionInProgress) .workflowExitOfferSource(presenter: self.exitOfferPresenter) { await self.purchaseHandler.resolveOffering(for: self.content) @@ -731,6 +751,10 @@ private struct PresentingPaywallModifier: ViewModifier { if !self.exitOfferPresenter.presentIfAvailable() { self.purchaseHandler.resetForNewSession() self.onDismiss?() + } else { + // Exit offer reuses purchaseHandler without a full reset (sessionPurchaseResult is + // still needed for eligibility), so clear this signal to avoid it firing again there. + self.purchaseHandler.clearWebCheckoutOpened() } } @@ -772,6 +796,9 @@ private struct PresentingPaywallModifier: ViewModifier { .onRestoreFailure { self.restoreFailure?($0) } + .onWebCheckoutOpened { + self.webCheckoutOpened?() + } .interactiveDismissDisabled(self.purchaseHandler.actionInProgress) } @@ -808,6 +835,7 @@ private struct PresentingPaywallBindingModifier: ViewModifier { var purchaseFailure: PurchaseFailureHandler? var restoreFailure: PurchaseFailureHandler? var onDismiss: (() -> Void)? + var webCheckoutOpened: WebCheckoutOpenedHandler? /// Owns the exit-offer lifecycle (sourcing + presentation state + transitions). @StateObject @@ -836,7 +864,8 @@ private struct PresentingPaywallBindingModifier: ViewModifier { restoreCompleted: PurchaseOrRestoreCompletedHandler?, purchaseFailure: PurchaseFailureHandler?, restoreFailure: PurchaseFailureHandler?, - onDismiss: (() -> Void)? + onDismiss: (() -> Void)?, + webCheckoutOpened: WebCheckoutOpenedHandler? ) { self._offering = offering self.presentationMode = presentationMode @@ -849,6 +878,7 @@ private struct PresentingPaywallBindingModifier: ViewModifier { self.purchaseFailure = purchaseFailure self.restoreFailure = restoreFailure self.onDismiss = onDismiss + self.webCheckoutOpened = webCheckoutOpened let handler = PurchaseHandler.default(performPurchase: myAppPurchaseLogic?.performPurchase, performRestore: myAppPurchaseLogic?.performRestore) self._purchaseHandler = .init(wrappedValue: handler) @@ -928,6 +958,9 @@ private struct PresentingPaywallBindingModifier: ViewModifier { .onRestoreFailure { self.restoreFailure?($0) } + .onWebCheckoutOpened { + self.webCheckoutOpened?() + } .interactiveDismissDisabled(self.purchaseHandler.actionInProgress) .workflowExitOfferSource(presenter: self.exitOfferPresenter) { offering @@ -971,6 +1004,9 @@ private struct PresentingPaywallBindingModifier: ViewModifier { .onRestoreFailure { self.restoreFailure?($0) } + .onWebCheckoutOpened { + self.webCheckoutOpened?() + } .interactiveDismissDisabled(self.purchaseHandler.actionInProgress) } @@ -1026,6 +1062,10 @@ private struct PresentingPaywallBindingModifier: ViewModifier { if !self.exitOfferPresenter.presentIfAvailable() { self.purchaseHandler.resetForNewSession() self.onDismiss?() + } else { + // Exit offer reuses purchaseHandler without a full reset (sessionPurchaseResult is + // still needed for eligibility), so clear this signal to avoid it firing again there. + self.purchaseHandler.clearWebCheckoutOpened() } } diff --git a/RevenueCatUI/View+PurchaseRestoreCompleted.swift b/RevenueCatUI/View+PurchaseRestoreCompleted.swift index 2269221c29..938276183f 100644 --- a/RevenueCatUI/View+PurchaseRestoreCompleted.swift +++ b/RevenueCatUI/View+PurchaseRestoreCompleted.swift @@ -39,6 +39,10 @@ public typealias PurchaseOfPackageStartedHandler = @MainActor @Sendable (_ packa /// A closure used for notifying of purchase cancellation. public typealias PurchaseCancelledHandler = @MainActor @Sendable () -> Void +/// A closure invoked when the user taps a web checkout CTA and leaves the app to complete payment +/// externally. +public typealias WebCheckoutOpenedHandler = @MainActor @Sendable () -> Void + /// A closure used to perform custom purchase logic implemented by your app. /// - Parameters: /// - package: The package to be purchased. @@ -244,6 +248,22 @@ extension View { return self.modifier(OnPurchaseCancelledModifier(handler: handler)) } + /// Invokes the given closure when the user taps a web checkout CTA and leaves the app to complete + /// payment externally. Distinct from ``onPurchaseCancelled(_:)``: the user has not cancelled. + /// + /// Example: + /// ```swift + /// PaywallView() + /// .onWebCheckoutOpened { + /// print("User left to complete web checkout") + /// } + /// ``` + public func onWebCheckoutOpened( + _ handler: @escaping WebCheckoutOpenedHandler + ) -> some View { + return self.modifier(OnWebCheckoutOpenedModifier(handler: handler)) + } + /// Invokes the given closure when a restore begins. /// Example: /// ```swift @@ -514,6 +534,22 @@ private struct OnPurchaseCancelledModifier: ViewModifier { } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +private struct OnWebCheckoutOpenedModifier: ViewModifier { + + let handler: WebCheckoutOpenedHandler + + func body(content: Content) -> some View { + content + .onPreferenceChange(WebCheckoutOpenedPreferenceKey.self) { id in + if id != nil { + self.handler() + } + } + } + +} + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) private struct OnRestoreStartedModifier: ViewModifier { diff --git a/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallViewAPI.swift b/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallViewAPI.swift index 0a3f1c4e7d..f5ff074b81 100644 --- a/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallViewAPI.swift +++ b/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallViewAPI.swift @@ -21,6 +21,7 @@ struct App: View { private var purchaseOfPackageStarted: PurchaseOfPackageStartedHandler = { (_: Package) in } private var purchaseCompleted: PurchaseCompletedHandler = { (_: StoreTransaction?, _: CustomerInfo) in } private var purchaseCancelled: PurchaseCancelledHandler = { () in } + private var webCheckoutOpened: WebCheckoutOpenedHandler = { () in } private var restoreStarted: RestoreStartedHandler = { } private var failureHandler: PurchaseFailureHandler = { (_: NSError) in } @@ -184,7 +185,8 @@ struct App: View { restoreCompleted: nil, purchaseFailure: nil, restoreFailure: nil, - onDismiss: nil) + onDismiss: nil, + webCheckoutOpened: self.webCheckoutOpened) } @ViewBuilder @@ -302,7 +304,8 @@ struct App: View { restoreCompleted: nil, purchaseFailure: nil, restoreFailure: nil, - onDismiss: nil) + onDismiss: nil, + webCheckoutOpened: self.webCheckoutOpened) } @State private var offeringBinding: Offering? @@ -349,7 +352,10 @@ struct App: View { restoreCompleted: nil, purchaseFailure: nil, restoreFailure: nil, - onDismiss: nil) + onDismiss: nil, + webCheckoutOpened: nil) + .presentPaywall(offering: self.$offeringBinding, + webCheckoutOpened: self.webCheckoutOpened) .presentPaywall(offering: self.$offeringBinding, fonts: self.fonts, presentationMode: .sheet, @@ -793,6 +799,7 @@ struct App: View { .onPurchaseCompleted(self.purchaseOrRestoreCompleted) .onPurchaseCompleted(self.purchaseCompleted) .onPurchaseCancelled(self.purchaseCancelled) + .onWebCheckoutOpened(self.webCheckoutOpened) .onRestoreStarted(self.restoreStarted) .onRestoreCompleted(self.purchaseOrRestoreCompleted) .onRequestedDismissal(self.requestedDismissal) diff --git a/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallViewControllerAPI.swift b/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallViewControllerAPI.swift index 6d619b975b..5677b73d5f 100644 --- a/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallViewControllerAPI.swift +++ b/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallViewControllerAPI.swift @@ -203,6 +203,8 @@ final class Delegate: PaywallViewControllerDelegate { func paywallViewControllerDidCancelPurchase(_ controller: PaywallViewController) {} + func paywallViewControllerDidOpenWebCheckout(_ controller: PaywallViewController) {} + func paywallViewController(_ controller: PaywallViewController, didFailPurchasingWith error: NSError) {} diff --git a/Tests/RevenueCatUITests/PaywallsV2/WorkflowPaywallViewTests.swift b/Tests/RevenueCatUITests/PaywallsV2/WorkflowPaywallViewTests.swift index 374cef61a0..47db10bb17 100644 --- a/Tests/RevenueCatUITests/PaywallsV2/WorkflowPaywallViewTests.swift +++ b/Tests/RevenueCatUITests/PaywallsV2/WorkflowPaywallViewTests.swift @@ -901,6 +901,23 @@ extension WorkflowPaywallViewTests { expect(customerInfo).toEventually(be(TestData.customerInfo)) } + @MainActor + func testOnWebCheckoutOpenedFiredInWorkflow() throws { + // PaywallsV2View must publish WebCheckoutOpenedPreferenceKey like the other preferences, or + // this never fires for V2 full-screen paywalls, the only surface with web checkout buttons. + let purchaseHandler: PurchaseHandler = .mock() + let context = try Self.makeContext(singleStepFallbackId: "step_terminal") + var fireCount = 0 + + _ = try WorkflowPurchaseObserver(purchaseHandler: purchaseHandler, context: context) + .onWebCheckoutOpened { fireCount += 1 } + .addToHierarchy() + + purchaseHandler.signalWebCheckoutOpened() + + expect(fireCount).toEventually(equal(1)) + } + @MainActor func testOnPurchaseCancelledFiredInWorkflow() throws { let purchaseHandler: PurchaseHandler = .cancelling() diff --git a/Tests/RevenueCatUITests/Purchasing/OnWebCheckoutOpenedModifierTests.swift b/Tests/RevenueCatUITests/Purchasing/OnWebCheckoutOpenedModifierTests.swift new file mode 100644 index 0000000000..2cbb8be9d6 --- /dev/null +++ b/Tests/RevenueCatUITests/Purchasing/OnWebCheckoutOpenedModifierTests.swift @@ -0,0 +1,129 @@ +// +// 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 +// +// OnWebCheckoutOpenedModifierTests.swift +// + +import Nimble +@_spi(Internal) @testable import RevenueCat +@testable import RevenueCatUI +import SwiftUI +import XCTest + +#if os(iOS) + +/// Verifies the `.onWebCheckoutOpened` modifier's `PreferenceKey` plumbing. +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@MainActor +final class OnWebCheckoutOpenedModifierTests: TestCase { + + func testOnWebCheckoutOpenedFiresForEachSignal() { + let handler: PurchaseHandler = .mock() + let fireCount: Atomic = .init(0) + + let view = ProbeView(handler: handler) { + fireCount.modify { $0 += 1 } + } + + let (window, _) = Self.host(view) + defer { + window.isHidden = true + window.rootViewController = nil + } + + expect(fireCount.value) == 0 + + // Mutating the handler directly isolates the preference/modifier plumbing from gesture handling. + handler.signalWebCheckoutOpened() + RunLoop.main.run(until: Date().addingTimeInterval(0.2)) + expect(fireCount.value) == 1 + + // Must fire again, not be deduped as an identical value. + handler.signalWebCheckoutOpened() + RunLoop.main.run(until: Date().addingTimeInterval(0.2)) + expect(fireCount.value) == 2 + } + + func testOnWebCheckoutOpenedFiresEvenWhenResetImmediatelyAfter() { + let handler: PurchaseHandler = .mock() + let fireCount: Atomic = .init(0) + + let view = ProbeView(handler: handler) { + fireCount.modify { $0 += 1 } + } + + let (window, _) = Self.host(view) + defer { + window.isHidden = true + window.rootViewController = nil + } + + expect(fireCount.value) == 0 + + // Mirrors handleMainPaywallDismiss: signal then immediately reset, no RunLoop spin in between. + handler.signalWebCheckoutOpened() + handler.resetForNewSession() + RunLoop.main.run(until: Date().addingTimeInterval(0.3)) + expect(fireCount.value) == 1 + } + + func testOnWebCheckoutOpenedDoesNotFireOnNewViewAfterExitOfferClear() { + // clearWebCheckoutOpened() must complete synchronously so a new view reusing this handler + // (the exit offer) doesn't see the stale signal as its own fresh one. + let handler: PurchaseHandler = .mock() + handler.signalWebCheckoutOpened() + handler.clearWebCheckoutOpened() + + let fireCount: Atomic = .init(0) + let view = ProbeView(handler: handler) { + fireCount.modify { $0 += 1 } + } + + let (window, _) = Self.host(view) + defer { + window.isHidden = true + window.rootViewController = nil + } + + RunLoop.main.run(until: Date().addingTimeInterval(0.2)) + expect(fireCount.value) == 0 + } + +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +private struct ProbeView: View { + + @ObservedObject var handler: PurchaseHandler + let onWebCheckoutOpened: WebCheckoutOpenedHandler + + var body: some View { + Color.clear + .preference(key: WebCheckoutOpenedPreferenceKey.self, value: self.handler.webCheckoutOpened) + .onWebCheckoutOpened(self.onWebCheckoutOpened) + } + +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +private extension OnWebCheckoutOpenedModifierTests { + + static func host(_ view: Content) -> (UIWindow, UIView) { + let controller = UIHostingController(rootView: view.frame(width: 100, height: 100)) + let window = UIWindow(frame: CGRect(origin: .zero, size: CGSize(width: 100, height: 100))) + window.rootViewController = controller + window.makeKeyAndVisible() + controller.view.layoutIfNeeded() + RunLoop.main.run(until: Date().addingTimeInterval(0.1)) + return (window, controller.view) + } + +} + +#endif diff --git a/Tests/RevenueCatUITests/Purchasing/PurchaseHandlerTests.swift b/Tests/RevenueCatUITests/Purchasing/PurchaseHandlerTests.swift index c0360008f3..cbfbd9f615 100644 --- a/Tests/RevenueCatUITests/Purchasing/PurchaseHandlerTests.swift +++ b/Tests/RevenueCatUITests/Purchasing/PurchaseHandlerTests.swift @@ -101,6 +101,31 @@ class PurchaseHandlerTests: TestCase { expect(handler.restoredCustomerInfo).to(beNil()) } + @MainActor + func testSignalWebCheckoutOpenedSetsANewUUID() async throws { + let handler: PurchaseHandler = .mock() + expect(handler.webCheckoutOpened).to(beNil()) + + handler.signalWebCheckoutOpened() + let firstID = handler.webCheckoutOpened + expect(firstID).toNot(beNil()) + + handler.signalWebCheckoutOpened() + expect(handler.webCheckoutOpened).toNot(equal(firstID)) + } + + @MainActor + func testResetForNewSessionClearsWebCheckoutOpened() async throws { + let handler: PurchaseHandler = .mock() + handler.signalWebCheckoutOpened() + expect(handler.webCheckoutOpened).toNot(beNil()) + + handler.resetForNewSession() + + // Cleared a tick later (see `deferredClearWebCheckoutOpened`), not synchronously. + await expect(handler.webCheckoutOpened).toEventually(beNil()) + } + func testCancelEventContainsProductIdentifierWhenCompletedByRevenueCat() async throws { let trackedEvents: Atomic<[PaywallEvent]> = .init([]) diff --git a/api/revenuecatui-api-ios-simulator.swiftinterface b/api/revenuecatui-api-ios-simulator.swiftinterface index 30bbb7549c..3b4739ba8d 100644 --- a/api/revenuecatui-api-ios-simulator.swiftinterface +++ b/api/revenuecatui-api-ios-simulator.swiftinterface @@ -365,6 +365,7 @@ extension RevenueCatUI.PaywallViewController : UIKit.UIAdaptivePresentationContr @objc(paywallViewController:didFinishPurchasingWithCustomerInfo:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishPurchasingWith customerInfo: RevenueCat.CustomerInfo) @objc(paywallViewController:didFinishPurchasingWithCustomerInfo:transaction:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishPurchasingWith customerInfo: RevenueCat.CustomerInfo, transaction: RevenueCat.StoreTransaction?) @objc(paywallViewControllerDidCancelPurchase:) optional func paywallViewControllerDidCancelPurchase(_ controller: RevenueCatUI.PaywallViewController) + @objc(paywallViewControllerDidOpenWebCheckout:) optional func paywallViewControllerDidOpenWebCheckout(_ controller: RevenueCatUI.PaywallViewController) @objc(paywallViewController:didFailPurchasingWithError:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFailPurchasingWith error: Foundation.NSError) @objc(paywallViewControllerDidStartRestore:) optional func paywallViewControllerDidStartRestore(_ controller: RevenueCatUI.PaywallViewController) @objc(paywallViewController:didFinishRestoringWithCustomerInfo:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishRestoringWith customerInfo: RevenueCat.CustomerInfo) @@ -412,20 +413,20 @@ extension SwiftUICore.View { @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View @available(iOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(tvOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View } public typealias PaywallTierChangeHandler = @_Concurrency.MainActor @Sendable (_ tier: RevenueCat.PaywallData.Tier, _ localizedName: Swift.String) -> Swift.Void @@ -481,6 +482,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -516,6 +518,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View diff --git a/api/revenuecatui-api-ios.swiftinterface b/api/revenuecatui-api-ios.swiftinterface index 5106fe465c..4b23fd981a 100644 --- a/api/revenuecatui-api-ios.swiftinterface +++ b/api/revenuecatui-api-ios.swiftinterface @@ -365,6 +365,7 @@ extension RevenueCatUI.PaywallViewController : UIKit.UIAdaptivePresentationContr @objc(paywallViewController:didFinishPurchasingWithCustomerInfo:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishPurchasingWith customerInfo: RevenueCat.CustomerInfo) @objc(paywallViewController:didFinishPurchasingWithCustomerInfo:transaction:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishPurchasingWith customerInfo: RevenueCat.CustomerInfo, transaction: RevenueCat.StoreTransaction?) @objc(paywallViewControllerDidCancelPurchase:) optional func paywallViewControllerDidCancelPurchase(_ controller: RevenueCatUI.PaywallViewController) + @objc(paywallViewControllerDidOpenWebCheckout:) optional func paywallViewControllerDidOpenWebCheckout(_ controller: RevenueCatUI.PaywallViewController) @objc(paywallViewController:didFailPurchasingWithError:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFailPurchasingWith error: Foundation.NSError) @objc(paywallViewControllerDidStartRestore:) optional func paywallViewControllerDidStartRestore(_ controller: RevenueCatUI.PaywallViewController) @objc(paywallViewController:didFinishRestoringWithCustomerInfo:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishRestoringWith customerInfo: RevenueCat.CustomerInfo) @@ -412,20 +413,20 @@ extension SwiftUICore.View { @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View @available(iOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(tvOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View } public typealias PaywallTierChangeHandler = @_Concurrency.MainActor @Sendable (_ tier: RevenueCat.PaywallData.Tier, _ localizedName: Swift.String) -> Swift.Void @@ -481,6 +482,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -516,6 +518,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View diff --git a/api/revenuecatui-api-macos.swiftinterface b/api/revenuecatui-api-macos.swiftinterface index e64db71c52..d5eb5b0ae9 100644 --- a/api/revenuecatui-api-macos.swiftinterface +++ b/api/revenuecatui-api-macos.swiftinterface @@ -200,20 +200,20 @@ extension SwiftUICore.View { @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View @available(iOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(tvOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View } public typealias PaywallTierChangeHandler = @_Concurrency.MainActor @Sendable (_ tier: RevenueCat.PaywallData.Tier, _ localizedName: Swift.String) -> Swift.Void @@ -269,6 +269,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -304,6 +305,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View diff --git a/api/revenuecatui-api-tvos-simulator.swiftinterface b/api/revenuecatui-api-tvos-simulator.swiftinterface index 5644db3c92..ddeb664de5 100644 --- a/api/revenuecatui-api-tvos-simulator.swiftinterface +++ b/api/revenuecatui-api-tvos-simulator.swiftinterface @@ -169,6 +169,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -204,6 +205,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View diff --git a/api/revenuecatui-api-tvos.swiftinterface b/api/revenuecatui-api-tvos.swiftinterface index d442144141..9b19f1b74d 100644 --- a/api/revenuecatui-api-tvos.swiftinterface +++ b/api/revenuecatui-api-tvos.swiftinterface @@ -169,6 +169,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -204,6 +205,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View diff --git a/api/revenuecatui-api-visionos-simulator.swiftinterface b/api/revenuecatui-api-visionos-simulator.swiftinterface index b87d2b82d9..ee25fd8d74 100644 --- a/api/revenuecatui-api-visionos-simulator.swiftinterface +++ b/api/revenuecatui-api-visionos-simulator.swiftinterface @@ -235,6 +235,7 @@ extension RevenueCatUI.PaywallViewController : UIKit.UIAdaptivePresentationContr @objc(paywallViewController:didFinishPurchasingWithCustomerInfo:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishPurchasingWith customerInfo: RevenueCat.CustomerInfo) @objc(paywallViewController:didFinishPurchasingWithCustomerInfo:transaction:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishPurchasingWith customerInfo: RevenueCat.CustomerInfo, transaction: RevenueCat.StoreTransaction?) @objc(paywallViewControllerDidCancelPurchase:) optional func paywallViewControllerDidCancelPurchase(_ controller: RevenueCatUI.PaywallViewController) + @objc(paywallViewControllerDidOpenWebCheckout:) optional func paywallViewControllerDidOpenWebCheckout(_ controller: RevenueCatUI.PaywallViewController) @objc(paywallViewController:didFailPurchasingWithError:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFailPurchasingWith error: Foundation.NSError) @objc(paywallViewControllerDidStartRestore:) optional func paywallViewControllerDidStartRestore(_ controller: RevenueCatUI.PaywallViewController) @objc(paywallViewController:didFinishRestoringWithCustomerInfo:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishRestoringWith customerInfo: RevenueCat.CustomerInfo) @@ -282,20 +283,20 @@ extension SwiftUICore.View { @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View @available(iOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(tvOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View } public typealias PaywallTierChangeHandler = @_Concurrency.MainActor @Sendable (_ tier: RevenueCat.PaywallData.Tier, _ localizedName: Swift.String) -> Swift.Void @@ -351,6 +352,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -386,6 +388,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View diff --git a/api/revenuecatui-api-visionos.swiftinterface b/api/revenuecatui-api-visionos.swiftinterface index ec8d35ca1f..5ecc6e6ffb 100644 --- a/api/revenuecatui-api-visionos.swiftinterface +++ b/api/revenuecatui-api-visionos.swiftinterface @@ -235,6 +235,7 @@ extension RevenueCatUI.PaywallViewController : UIKit.UIAdaptivePresentationContr @objc(paywallViewController:didFinishPurchasingWithCustomerInfo:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishPurchasingWith customerInfo: RevenueCat.CustomerInfo) @objc(paywallViewController:didFinishPurchasingWithCustomerInfo:transaction:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishPurchasingWith customerInfo: RevenueCat.CustomerInfo, transaction: RevenueCat.StoreTransaction?) @objc(paywallViewControllerDidCancelPurchase:) optional func paywallViewControllerDidCancelPurchase(_ controller: RevenueCatUI.PaywallViewController) + @objc(paywallViewControllerDidOpenWebCheckout:) optional func paywallViewControllerDidOpenWebCheckout(_ controller: RevenueCatUI.PaywallViewController) @objc(paywallViewController:didFailPurchasingWithError:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFailPurchasingWith error: Foundation.NSError) @objc(paywallViewControllerDidStartRestore:) optional func paywallViewControllerDidStartRestore(_ controller: RevenueCatUI.PaywallViewController) @objc(paywallViewController:didFinishRestoringWithCustomerInfo:) optional func paywallViewController(_ controller: RevenueCatUI.PaywallViewController, didFinishRestoringWith customerInfo: RevenueCat.CustomerInfo) @@ -282,20 +283,20 @@ extension SwiftUICore.View { @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View @available(iOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(tvOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View } public typealias PaywallTierChangeHandler = @_Concurrency.MainActor @Sendable (_ tier: RevenueCat.PaywallData.Tier, _ localizedName: Swift.String) -> Swift.Void @@ -351,6 +352,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -386,6 +388,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View diff --git a/api/revenuecatui-api-watchos-simulator.swiftinterface b/api/revenuecatui-api-watchos-simulator.swiftinterface index 03d128c761..df9a111070 100644 --- a/api/revenuecatui-api-watchos-simulator.swiftinterface +++ b/api/revenuecatui-api-watchos-simulator.swiftinterface @@ -198,20 +198,20 @@ extension SwiftUICore.View { @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View @available(iOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(tvOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View } public typealias PurchaseOrRestoreCompletedHandler = @_Concurrency.MainActor @Sendable (RevenueCat.CustomerInfo) -> Swift.Void @@ -224,6 +224,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -259,6 +260,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View diff --git a/api/revenuecatui-api-watchos.swiftinterface b/api/revenuecatui-api-watchos.swiftinterface index 39b2ed3084..340ffb50da 100644 --- a/api/revenuecatui-api-watchos.swiftinterface +++ b/api/revenuecatui-api-watchos.swiftinterface @@ -198,20 +198,20 @@ extension SwiftUICore.View { @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(requiredEntitlementIdentifier:offering:fonts:presentationMode:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(requiredEntitlementIdentifier: Swift.String, offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View @available(iOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(tvOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(watchOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macOS, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") @available(macCatalyst, deprecated: 1, renamed: "presentPaywallIfNeeded(offering:fonts:presentationMode:shouldDisplay:purchaseStarted:purchaseCompleted:purchaseCancelled:restoreStarted:restoreCompleted:purchaseFailure:restoreFailure:onDismiss:)") - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: @escaping RevenueCatUI.PurchaseStartedHandler, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywallIfNeeded(offering: RevenueCat.Offering? = nil, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, shouldDisplay: @escaping @Sendable (RevenueCat.CustomerInfo) -> Swift.Bool, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View - @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func presentPaywall(offering: SwiftUICore.Binding, fonts: any RevenueCatUI.PaywallFontProvider = DefaultPaywallFontProvider(), presentationMode: RevenueCatUI.PaywallPresentationMode = .default, myAppPurchaseLogic: RevenueCatUI.MyAppPurchaseLogic? = nil, purchaseStarted: RevenueCatUI.PurchaseOfPackageStartedHandler? = nil, purchaseCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseCancelled: RevenueCatUI.PurchaseCancelledHandler? = nil, restoreStarted: RevenueCatUI.RestoreStartedHandler? = nil, restoreCompleted: RevenueCatUI.PurchaseOrRestoreCompletedHandler? = nil, purchaseFailure: RevenueCatUI.PurchaseFailureHandler? = nil, restoreFailure: RevenueCatUI.PurchaseFailureHandler? = nil, onDismiss: (() -> Swift.Void)? = nil, webCheckoutOpened: RevenueCatUI.WebCheckoutOpenedHandler? = nil) -> some SwiftUICore.View } public typealias PurchaseOrRestoreCompletedHandler = @_Concurrency.MainActor @Sendable (RevenueCat.CustomerInfo) -> Swift.Void @@ -224,6 +224,7 @@ public typealias PurchaseCompletedHandler = @_Concurrency.MainActor @Sendable (_ public typealias PurchaseStartedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void public typealias PurchaseOfPackageStartedHandler = @_Concurrency.MainActor @Sendable (_ package: RevenueCat.Package) -> Swift.Void public typealias PurchaseCancelledHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void +public typealias WebCheckoutOpenedHandler = @_Concurrency.MainActor @Sendable () -> Swift.Void @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public typealias PerformPurchase = @_Concurrency.MainActor @Sendable (_ packageToPurchase: RevenueCat.Package) async -> (userCancelled: Swift.Bool, error: (any Swift.Error)?) @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -259,6 +260,8 @@ extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onPurchaseCancelled(_ handler: @escaping RevenueCatUI.PurchaseCancelledHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onWebCheckoutOpened(_ handler: @escaping RevenueCatUI.WebCheckoutOpenedHandler) -> some SwiftUICore.View + @_Concurrency.MainActor @preconcurrency public func onRestoreStarted(_ handler: @escaping RevenueCatUI.RestoreStartedHandler) -> some SwiftUICore.View @_Concurrency.MainActor @preconcurrency public func onRestoreCompleted(_ handler: @escaping RevenueCatUI.PurchaseOrRestoreCompletedHandler) -> some SwiftUICore.View