From 5cf1dfd3a5001b0811b8119907e8093ae5ca5a77 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 15 Jul 2026 20:18:13 +0000 Subject: [PATCH 1/5] feat(paywalls): public API surface for web_view messages (1/7) Add PaywallWebViewMessage/Value/Controller/Action types and API baselines. Controller post APIs are no-ops until the session PR wires WebKit. Co-authored-by: Jacob Rakidzich --- RevenueCat.xcodeproj/project.pbxproj | 14 ++ .../WebView/PaywallWebViewAPI.swift | 205 ++++++++++++++++++ .../AllAPITests.xcodeproj/project.pbxproj | 4 + .../PaywallWebViewAPI.swift | 77 +++++++ .../PaywallsV2/PaywallWebViewValueTests.swift | 59 +++++ ...enuecatui-api-ios-simulator.swiftinterface | 62 ++++++ api/revenuecatui-api-ios.swiftinterface | 62 ++++++ api/revenuecatui-api-macos.swiftinterface | 62 ++++++ ...atui-api-visionos-simulator.swiftinterface | 62 ++++++ api/revenuecatui-api-visionos.swiftinterface | 62 ++++++ ...catui-api-watchos-simulator.swiftinterface | 62 ++++++ api/revenuecatui-api-watchos.swiftinterface | 62 ++++++ 12 files changed, 793 insertions(+) create mode 100644 RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift create mode 100644 Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallWebViewAPI.swift create mode 100644 Tests/RevenueCatUITests/PaywallsV2/PaywallWebViewValueTests.swift diff --git a/RevenueCat.xcodeproj/project.pbxproj b/RevenueCat.xcodeproj/project.pbxproj index 996c1ac30c..0f4bd8f8c2 100644 --- a/RevenueCat.xcodeproj/project.pbxproj +++ b/RevenueCat.xcodeproj/project.pbxproj @@ -107,6 +107,7 @@ 16DA8ECD2E4EE33700283940 /* ImageComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DA8ECC2E4EE33700283940 /* ImageComponentTests.swift */; }; 16DA8EDF2E4F6A6600283940 /* PaywallVideoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DA8EDE2E4F6A6600283940 /* PaywallVideoComponent.swift */; }; 16DA8EF42E4F7A2500283940 /* VideoComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DA8EF32E4F7A2500283940 /* VideoComponentTests.swift */; }; + FA4A2DF41FC434A9401F08CC /* PaywallWebViewAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D0C57ECDF0E7F1A5B4418FF /* PaywallWebViewAPI.swift */; }; 16DA8F1E2E4FB6E200283940 /* ImageComponent.json in Resources */ = {isa = PBXBuildFile; fileRef = 16DA8F1B2E4FB6E200283940 /* ImageComponent.json */; }; 16DA8F1F2E4FB6E200283940 /* VideoComponent.json in Resources */ = {isa = PBXBuildFile; fileRef = 16DA8F1C2E4FB6E200283940 /* VideoComponent.json */; }; 16E146AD2E99F3480089B609 /* TransactionNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16E146AB2E99F1E20089B609 /* TransactionNotifications.swift */; }; @@ -1636,6 +1637,8 @@ 16DA8ECC2E4EE33700283940 /* ImageComponentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageComponentTests.swift; sourceTree = ""; }; 16DA8EDE2E4F6A6600283940 /* PaywallVideoComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallVideoComponent.swift; sourceTree = ""; }; 16DA8EF32E4F7A2500283940 /* VideoComponentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoComponentTests.swift; sourceTree = ""; }; + 9D0C57ECDF0E7F1A5B4418FF /* PaywallWebViewAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallWebViewAPI.swift; sourceTree = ""; }; + 686562C08D953A27986DB276 /* PaywallWebViewValueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallWebViewValueTests.swift; sourceTree = ""; }; 16DA8F1B2E4FB6E200283940 /* ImageComponent.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ImageComponent.json; sourceTree = ""; }; 16DA8F1C2E4FB6E200283940 /* VideoComponent.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = VideoComponent.json; sourceTree = ""; }; 16E146AB2E99F1E20089B609 /* TransactionNotifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionNotifications.swift; sourceTree = ""; }; @@ -3165,6 +3168,7 @@ 030890822D2B77DD0069677B /* PaywallsV2 */ = { isa = PBXGroup; children = ( + 686562C08D953A27986DB276 /* PaywallWebViewValueTests.swift */, 802593842FE07057005AF6DF /* PaywallStateStoreTests.swift */, 16A9F7B62FAA22D0008E8A4D /* VideoComponentViewTests.swift */, A9D45E4EAFAD4C0385BEDFB3 /* VideoPlayerViewTests.swift */, @@ -3297,6 +3301,14 @@ path = Video; sourceTree = ""; }; + EB23E44596DD9714E81840CF /* WebView */ = { + isa = PBXGroup; + children = ( + 9D0C57ECDF0E7F1A5B4418FF /* PaywallWebViewAPI.swift */, + ); + path = WebView; + sourceTree = ""; + }; 1699BD5C2EEFBEEC002001FB /* DefaultPaywall */ = { isa = PBXGroup; children = ( @@ -3387,6 +3399,7 @@ 0387D4AD2EC58AA5008E4A6B /* Countdown */, E1C0A00BBEEF0001CCDD0001 /* Header */, 164681CD2E6B577600854AA5 /* Video */, + EB23E44596DD9714E81840CF /* WebView */, 2C7457472CEA66AB004ACE52 /* ComponentsView.swift */, 7707A94A2CAD936A006E0313 /* Button */, 03C06FC82D479C6300600693 /* Carousel */, @@ -8233,6 +8246,7 @@ 164681D02E6B577600854AA5 /* VideoComponentView.swift in Sources */, 164681D12E6B577600854AA5 /* VideoPlayerViewUIView.swift in Sources */, 164681D62E6B577600854AA5 /* VideoPlayerLayerUIView.swift in Sources */, + FA4A2DF41FC434A9401F08CC /* PaywallWebViewAPI.swift in Sources */, DBAA1FC22F8D4ED8000E8C81 /* HeaderNestedHeroZLayerSafeAreaPreview.swift in Sources */, 164681D22E6B577600854AA5 /* VideoComponentViewModel.swift in Sources */, 2C7457422CE81107004ACE52 /* IntroOfferEligibilityContext.swift in Sources */, diff --git a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift new file mode 100644 index 0000000000..5ba2a3fe3b --- /dev/null +++ b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift @@ -0,0 +1,205 @@ +import Foundation +import SwiftUI +// swiftlint:disable missing_docs + +#if !os(tvOS) // For Paywalls V2 + +/// A validated message sent from a Paywalls V2 `web_view` component to your app. +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessage: Sendable, Equatable { + + /// The identifier of the `web_view` component that produced this message. + public let componentID: String + + /// The message type, e.g. `"rc:step-complete"`. + public let type: String + + /// The responses collected by the web flow. Only populated for `"rc:step-complete"` messages. + public let responses: [String: PaywallWebViewValue]? + + /// The error reported by the web content. Only populated for `"rc:error"` messages. + public let error: String? + + public init( + componentID: String, + type: String, + responses: [String: PaywallWebViewValue]? = nil, + error: String? = nil + ) { + self.componentID = componentID + self.type = type + self.responses = responses + self.error = error + } + +} + +/// A JSON-compatible value exchanged between a Paywalls V2 `web_view` component and your app. +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { + + private indirect enum Storage: Sendable, Equatable, Hashable { + case string(String) + case number(Double) + case bool(Bool) + case array([PaywallWebViewValue]) + case object([String: PaywallWebViewValue]) + case null + } + + private let storage: Storage + + private init(_ storage: Storage) { + self.storage = storage + } + + /// Creates a string value. + public static func string(_ value: String) -> Self { Self(.string(value)) } + + /// Creates a numeric value. Non-finite values normalize to ``null`` because JSON cannot encode them. + public static func number(_ value: Double) -> Self { value.isFinite ? Self(.number(value)) : .null } + + /// Creates a boolean value. + public static func bool(_ value: Bool) -> Self { Self(.bool(value)) } + + /// Creates an array value. + public static func array(_ value: [PaywallWebViewValue]) -> Self { Self(.array(value)) } + + /// Creates an object (dictionary) value. + public static func object(_ value: [String: PaywallWebViewValue]) -> Self { Self(.object(value)) } + + /// A null value. + public static var null: Self { Self(.null) } + + public var stringValue: String? { + if case .string(let value) = self.storage { return value } + return nil + } + + public var numberValue: Double? { + if case .number(let value) = self.storage { return value } + return nil + } + + public var boolValue: Bool? { + if case .bool(let value) = self.storage { return value } + return nil + } + + public var arrayValue: [PaywallWebViewValue]? { + if case .array(let value) = self.storage { return value } + return nil + } + + public var objectValue: [String: PaywallWebViewValue]? { + if case .object(let value) = self.storage { return value } + return nil + } + + public var isNull: Bool { + if case .null = self.storage { return true } + return false + } + + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + + if container.decodeNil() { + self = .null + } else if let value = try? container.decode(Bool.self) { + self = .bool(value) + } else if let value = try? container.decode(Double.self) { + self = .number(value) + } else if let value = try? container.decode(String.self) { + self = .string(value) + } else if let value = try? container.decode([PaywallWebViewValue].self) { + self = .array(value) + } else { + self = .object(try container.decode([String: PaywallWebViewValue].self)) + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + + switch self.storage { + case .string(let value): + try container.encode(value) + case .number(let value): + try container.encode(value) + case .bool(let value): + try container.encode(value) + case .array(let value): + try container.encode(value) + case .object(let value): + try container.encode(value) + case .null: + try container.encodeNil() + } + } + +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@MainActor +public struct PaywallWebViewController { + + init() {} + + public func postVariables(componentID: String, variables: [String: PaywallWebViewValue]) { + // Session wiring lands in a later PR; public API is inert until then. + } + + public func postMessage(componentID: String, type: String, variables: [String: PaywallWebViewValue]) { + // Session wiring lands in a later PR; public API is inert until then. + } + +} + +/// A wrapper for the Paywalls V2 `web_view` message handler. +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessageAction { + + private let action: @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void + + public init( + _ action: @escaping @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void + ) { + self.action = action + } + + @MainActor + public func callAsFunction(_ message: PaywallWebViewMessage, _ controller: PaywallWebViewController) { + self.action(message, controller) + } + +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +struct PaywallWebViewMessageActionKey: EnvironmentKey { + static let defaultValue: PaywallWebViewMessageAction? = nil +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension EnvironmentValues { + + var paywallWebViewMessageAction: PaywallWebViewMessageAction? { + get { self[PaywallWebViewMessageActionKey.self] } + set { self[PaywallWebViewMessageActionKey.self] = newValue } + } + +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension View { + + /// Invokes the given closure when a Paywalls V2 `web_view` component sends a message. + public func onPaywallWebViewMessage( + _ action: @escaping @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void + ) -> some View { + self.environment(\.paywallWebViewMessageAction, PaywallWebViewMessageAction(action)) + } + +} + +#endif diff --git a/Tests/APITesters/AllAPITests/AllAPITests.xcodeproj/project.pbxproj b/Tests/APITesters/AllAPITests/AllAPITests.xcodeproj/project.pbxproj index 9cc8116989..74a25fd257 100644 --- a/Tests/APITesters/AllAPITests/AllAPITests.xcodeproj/project.pbxproj +++ b/Tests/APITesters/AllAPITests/AllAPITests.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 1E8A60812CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E8A60802CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift */; }; + B096F58208E0AA6582F34133 /* PaywallWebViewAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0DC08831A62751743D823FA /* PaywallWebViewAPI.swift */; }; 1EB697C22CD26218003000FC /* WebPurchaseRedemptionResultAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EB697C12CD26218003000FC /* WebPurchaseRedemptionResultAPI.swift */; }; 2D4C60E12C5AD1BC00A29FD2 /* AllAPITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D4C60D82C5AD1BC00A29FD2 /* AllAPITests.framework */; }; 2D4C60E62C5AD1BC00A29FD2 /* AllAPITestsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4C60E52C5AD1BC00A29FD2 /* AllAPITestsTests.swift */; }; @@ -228,6 +229,7 @@ /* Begin PBXFileReference section */ 1E8A60802CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedeemWebPurchasesAPI.swift; sourceTree = ""; }; + B0DC08831A62751743D823FA /* PaywallWebViewAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallWebViewAPI.swift; sourceTree = ""; }; 1EB697C12CD26218003000FC /* WebPurchaseRedemptionResultAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebPurchaseRedemptionResultAPI.swift; sourceTree = ""; }; 2D4C60D82C5AD1BC00A29FD2 /* AllAPITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AllAPITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2D4C60DB2C5AD1BC00A29FD2 /* AllAPITests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AllAPITests.h; sourceTree = ""; }; @@ -645,6 +647,7 @@ children = ( FD33CD722D035876000D13A4 /* CustomerCenterViewControllerAPI.swift */, 2D4C622D2C5ADA6700A29FD2 /* PaywallViewAPI.swift */, + B0DC08831A62751743D823FA /* PaywallWebViewAPI.swift */, 1E8A60802CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift */, 2D4C622B2C5ADA6700A29FD2 /* PaywallViewControllerAPI.swift */, 2D4C622C2C5ADA6700A29FD2 /* main.swift */, @@ -1119,6 +1122,7 @@ FDCC983A2D0A0FD500F5854B /* CustomerCenterViewAPI.swift in Sources */, 2D4C62302C5ADA6700A29FD2 /* PaywallViewControllerAPI.swift in Sources */, 1E8A60812CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift in Sources */, + B096F58208E0AA6582F34133 /* PaywallWebViewAPI.swift in Sources */, 2D4C622E2C5ADA6700A29FD2 /* PaywallViewAPI.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallWebViewAPI.swift b/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallWebViewAPI.swift new file mode 100644 index 0000000000..a8a2986ca9 --- /dev/null +++ b/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallWebViewAPI.swift @@ -0,0 +1,77 @@ +// +// PaywallWebViewAPI.swift +// RevenueCatUISwiftAPITester +// +// Compile-time checks for the Paywalls V2 web_view public API surface. +// + +import RevenueCat +import RevenueCatUI +import SwiftUI + +#if !os(tvOS) // For Paywalls V2 + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +struct PaywallWebViewApp: View { + + var body: some View { + Text("") + .onPaywallWebViewMessage { (message: PaywallWebViewMessage, controller: PaywallWebViewController) in + let componentID: String = message.componentID + let type: String = message.type + let responses: [String: PaywallWebViewValue]? = message.responses + let error: String? = message.error + + controller.postVariables( + componentID: componentID, + variables: ["custom": .object(["plan": .string("annual")])] + ) + controller.postMessage(componentID: componentID, type: type, variables: [:]) + + _ = (responses, error) + } + } + +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +func checkPaywallWebViewMessageAPI() { + let message = PaywallWebViewMessage( + componentID: "", + type: "rc:step-complete", + responses: ["selected_plan": .string("annual")], + error: nil + ) + let sameMessage: Bool = message == message + _ = sameMessage +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +func checkPaywallWebViewValueAPI() { + let string: PaywallWebViewValue = .string("s") + let number: PaywallWebViewValue = .number(1.5) + let bool: PaywallWebViewValue = .bool(true) + let array: PaywallWebViewValue = .array([string, number]) + let object: PaywallWebViewValue = .object(["key": bool]) + let null: PaywallWebViewValue = .null + + let _: String? = string.stringValue + let _: Double? = number.numberValue + let _: Bool? = bool.boolValue + let _: [PaywallWebViewValue]? = array.arrayValue + let _: [String: PaywallWebViewValue]? = object.objectValue + let _: Bool = null.isNull + let _: Set = [string, number] +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@MainActor +func checkPaywallWebViewMessageActionAPI( + message: PaywallWebViewMessage, + controller: PaywallWebViewController +) { + let action = PaywallWebViewMessageAction { (_: PaywallWebViewMessage, _: PaywallWebViewController) in } + action(message, controller) +} + +#endif diff --git a/Tests/RevenueCatUITests/PaywallsV2/PaywallWebViewValueTests.swift b/Tests/RevenueCatUITests/PaywallsV2/PaywallWebViewValueTests.swift new file mode 100644 index 0000000000..a593eeb9c5 --- /dev/null +++ b/Tests/RevenueCatUITests/PaywallsV2/PaywallWebViewValueTests.swift @@ -0,0 +1,59 @@ +// +// Copyright RevenueCat Inc. All Rights Reserved. +// + +@testable import RevenueCatUI +import XCTest + +#if !os(tvOS) + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +final class PaywallWebViewValueTests: TestCase { + + func testFactoryAccessorsAndCodableRoundTrip() throws { + let value: PaywallWebViewValue = .object([ + "string": .string("value"), + "number": .number(1.25), + "bool": .bool(true), + "array": .array([.null, .string("x")]), + "object": .object(["nested": .bool(false)]), + "null": .null + ]) + + let decoded = try JSONDecoder().decode( + PaywallWebViewValue.self, + from: try JSONEncoder().encode(value) + ) + + XCTAssertEqual(decoded, value) + XCTAssertEqual(decoded.objectValue?["string"]?.stringValue, "value") + XCTAssertEqual(decoded.objectValue?["number"]?.numberValue, 1.25) + XCTAssertEqual(decoded.objectValue?["bool"]?.boolValue, true) + XCTAssertTrue(decoded.objectValue?["null"]?.isNull == true) + } + + func testNumberBoolDisambiguation() throws { + let decoded = try JSONDecoder().decode( + PaywallWebViewValue.self, + from: Data(#"{"bool":true,"number":1}"#.utf8) + ) + + XCTAssertEqual(decoded.objectValue?["bool"]?.boolValue, true) + XCTAssertNil(decoded.objectValue?["bool"]?.numberValue) + XCTAssertEqual(decoded.objectValue?["number"]?.numberValue, 1) + } + + func testNonFiniteNumbersNormalizeToNullAndEncode() throws { + XCTAssertTrue(PaywallWebViewValue.number(.nan).isNull) + XCTAssertTrue(PaywallWebViewValue.number(.infinity).isNull) + XCTAssertTrue(PaywallWebViewValue.number(-.infinity).isNull) + XCTAssertNil(PaywallWebViewValue.number(.nan).numberValue) + + let value: PaywallWebViewValue = .object(["bad": .number(.nan)]) + XCTAssertNoThrow(try JSONEncoder().encode(value)) + XCTAssertEqual(PaywallWebViewValue.number(-0.0), .number(0.0)) + } + +} + +#endif diff --git a/api/revenuecatui-api-ios-simulator.swiftinterface b/api/revenuecatui-api-ios-simulator.swiftinterface index 30bbb7549c..428cfba3b0 100644 --- a/api/revenuecatui-api-ios-simulator.swiftinterface +++ b/api/revenuecatui-api-ios-simulator.swiftinterface @@ -309,6 +309,66 @@ extension RevenueCat.Purchases { @available(iOS 15.0, macOS 12.0, *) @_Concurrency.MainActor @objc final public func presentPaywall(from url: Foundation.URL) -> Swift.Bool } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { + public let componentID: Swift.String + public let type: Swift.String + public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? + public let error: Swift.String? + public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) + public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { + public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue + public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue + public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue + public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static var null: RevenueCatUI.PaywallWebViewValue { + get + } + public var stringValue: Swift.String? { + get + } + public var numberValue: Swift.Double? { + get + } + public var boolValue: Swift.Bool? { + get + } + public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { + get + } + public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { + get + } + public var isNull: Swift.Bool { + get + } + public init(from decoder: any Swift.Decoder) throws + public func encode(to encoder: any Swift.Encoder) throws + public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@_Concurrency.MainActor public struct PaywallWebViewController { + @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) + @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessageAction { + public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) + @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension SwiftUICore.View { + @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View + +} @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) @objc(RCPaywallFooterViewController) @_Concurrency.MainActor @preconcurrency final public class PaywallFooterViewController : RevenueCatUI.PaywallViewController { @_Concurrency.MainActor @preconcurrency public init(offering: RevenueCat.Offering? = nil, performPurchase: @escaping RevenueCatUI.PerformPurchase, performRestore: @escaping RevenueCatUI.PerformRestore, dismissRequestedHandler: ((_ controller: RevenueCatUI.PaywallViewController) -> Swift.Void)? = nil) @@ -546,5 +606,7 @@ extension RevenueCatUI.CustomerCenterNavigationLink : Swift.Sendable {} @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-ios.swiftinterface b/api/revenuecatui-api-ios.swiftinterface index 5106fe465c..9514729189 100644 --- a/api/revenuecatui-api-ios.swiftinterface +++ b/api/revenuecatui-api-ios.swiftinterface @@ -309,6 +309,66 @@ extension RevenueCat.Purchases { @available(iOS 15.0, macOS 12.0, *) @_Concurrency.MainActor @objc final public func presentPaywall(from url: Foundation.URL) -> Swift.Bool } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { + public let componentID: Swift.String + public let type: Swift.String + public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? + public let error: Swift.String? + public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) + public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { + public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue + public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue + public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue + public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static var null: RevenueCatUI.PaywallWebViewValue { + get + } + public var stringValue: Swift.String? { + get + } + public var numberValue: Swift.Double? { + get + } + public var boolValue: Swift.Bool? { + get + } + public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { + get + } + public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { + get + } + public var isNull: Swift.Bool { + get + } + public init(from decoder: any Swift.Decoder) throws + public func encode(to encoder: any Swift.Encoder) throws + public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@_Concurrency.MainActor public struct PaywallWebViewController { + @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) + @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessageAction { + public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) + @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension SwiftUICore.View { + @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View + +} @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) @objc(RCPaywallFooterViewController) @_Concurrency.MainActor @preconcurrency final public class PaywallFooterViewController : RevenueCatUI.PaywallViewController { @_Concurrency.MainActor @preconcurrency public init(offering: RevenueCat.Offering? = nil, performPurchase: @escaping RevenueCatUI.PerformPurchase, performRestore: @escaping RevenueCatUI.PerformRestore, dismissRequestedHandler: ((_ controller: RevenueCatUI.PaywallViewController) -> Swift.Void)? = nil) @@ -546,5 +606,7 @@ extension RevenueCatUI.CustomerCenterNavigationLink : Swift.Sendable {} @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-macos.swiftinterface b/api/revenuecatui-api-macos.swiftinterface index e64db71c52..d7553c3e37 100644 --- a/api/revenuecatui-api-macos.swiftinterface +++ b/api/revenuecatui-api-macos.swiftinterface @@ -168,6 +168,66 @@ open class CustomPaywallFontProvider : RevenueCatUI.PaywallFontProvider { @available(tvOS, unavailable, introduced: 15.0, message: "RevenueCatUI does not support tvOS yet") public typealias Body = @_opaqueReturnTypeOf("$s12RevenueCatUI11PaywallViewV4bodyQrvp", 0) __ } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { + public let componentID: Swift.String + public let type: Swift.String + public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? + public let error: Swift.String? + public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) + public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { + public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue + public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue + public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue + public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static var null: RevenueCatUI.PaywallWebViewValue { + get + } + public var stringValue: Swift.String? { + get + } + public var numberValue: Swift.Double? { + get + } + public var boolValue: Swift.Bool? { + get + } + public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { + get + } + public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { + get + } + public var isNull: Swift.Bool { + get + } + public init(from decoder: any Swift.Decoder) throws + public func encode(to encoder: any Swift.Encoder) throws + public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@_Concurrency.MainActor public struct PaywallWebViewController { + @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) + @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessageAction { + public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) + @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension SwiftUICore.View { + @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View + +} @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onWebPurchaseRedemptionAttempt(perform completion: @escaping @Sendable (RevenueCat.WebPurchaseRedemptionResult) -> Swift.Void) -> some SwiftUICore.View @@ -324,5 +384,7 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-visionos-simulator.swiftinterface b/api/revenuecatui-api-visionos-simulator.swiftinterface index b87d2b82d9..7369428ec5 100644 --- a/api/revenuecatui-api-visionos-simulator.swiftinterface +++ b/api/revenuecatui-api-visionos-simulator.swiftinterface @@ -179,6 +179,66 @@ extension RevenueCat.Purchases { @available(iOS 15.0, macOS 12.0, *) @_Concurrency.MainActor @objc final public func presentPaywall(from url: Foundation.URL) -> Swift.Bool } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { + public let componentID: Swift.String + public let type: Swift.String + public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? + public let error: Swift.String? + public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) + public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { + public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue + public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue + public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue + public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static var null: RevenueCatUI.PaywallWebViewValue { + get + } + public var stringValue: Swift.String? { + get + } + public var numberValue: Swift.Double? { + get + } + public var boolValue: Swift.Bool? { + get + } + public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { + get + } + public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { + get + } + public var isNull: Swift.Bool { + get + } + public init(from decoder: any Swift.Decoder) throws + public func encode(to encoder: any Swift.Encoder) throws + public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@_Concurrency.MainActor public struct PaywallWebViewController { + @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) + @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessageAction { + public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) + @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension SwiftUICore.View { + @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View + +} @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) @objc(RCPaywallFooterViewController) @_Concurrency.MainActor @preconcurrency final public class PaywallFooterViewController : RevenueCatUI.PaywallViewController { @_Concurrency.MainActor @preconcurrency public init(offering: RevenueCat.Offering? = nil, performPurchase: @escaping RevenueCatUI.PerformPurchase, performRestore: @escaping RevenueCatUI.PerformRestore, dismissRequestedHandler: ((_ controller: RevenueCatUI.PaywallViewController) -> Swift.Void)? = nil) @@ -406,5 +466,7 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-visionos.swiftinterface b/api/revenuecatui-api-visionos.swiftinterface index ec8d35ca1f..cccba66c64 100644 --- a/api/revenuecatui-api-visionos.swiftinterface +++ b/api/revenuecatui-api-visionos.swiftinterface @@ -179,6 +179,66 @@ extension RevenueCat.Purchases { @available(iOS 15.0, macOS 12.0, *) @_Concurrency.MainActor @objc final public func presentPaywall(from url: Foundation.URL) -> Swift.Bool } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { + public let componentID: Swift.String + public let type: Swift.String + public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? + public let error: Swift.String? + public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) + public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { + public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue + public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue + public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue + public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static var null: RevenueCatUI.PaywallWebViewValue { + get + } + public var stringValue: Swift.String? { + get + } + public var numberValue: Swift.Double? { + get + } + public var boolValue: Swift.Bool? { + get + } + public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { + get + } + public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { + get + } + public var isNull: Swift.Bool { + get + } + public init(from decoder: any Swift.Decoder) throws + public func encode(to encoder: any Swift.Encoder) throws + public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@_Concurrency.MainActor public struct PaywallWebViewController { + @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) + @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessageAction { + public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) + @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension SwiftUICore.View { + @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View + +} @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) @objc(RCPaywallFooterViewController) @_Concurrency.MainActor @preconcurrency final public class PaywallFooterViewController : RevenueCatUI.PaywallViewController { @_Concurrency.MainActor @preconcurrency public init(offering: RevenueCat.Offering? = nil, performPurchase: @escaping RevenueCatUI.PerformPurchase, performRestore: @escaping RevenueCatUI.PerformRestore, dismissRequestedHandler: ((_ controller: RevenueCatUI.PaywallViewController) -> Swift.Void)? = nil) @@ -406,5 +466,7 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-watchos-simulator.swiftinterface b/api/revenuecatui-api-watchos-simulator.swiftinterface index 03d128c761..7038282c5d 100644 --- a/api/revenuecatui-api-watchos-simulator.swiftinterface +++ b/api/revenuecatui-api-watchos-simulator.swiftinterface @@ -166,6 +166,66 @@ open class CustomPaywallFontProvider : RevenueCatUI.PaywallFontProvider { @available(tvOS, unavailable, introduced: 15.0, message: "RevenueCatUI does not support tvOS yet") public typealias Body = @_opaqueReturnTypeOf("$s12RevenueCatUI11PaywallViewV4bodyQrvp", 0) __ } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { + public let componentID: Swift.String + public let type: Swift.String + public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? + public let error: Swift.String? + public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) + public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { + public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue + public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue + public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue + public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static var null: RevenueCatUI.PaywallWebViewValue { + get + } + public var stringValue: Swift.String? { + get + } + public var numberValue: Swift.Double? { + get + } + public var boolValue: Swift.Bool? { + get + } + public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { + get + } + public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { + get + } + public var isNull: Swift.Bool { + get + } + public init(from decoder: any Swift.Decoder) throws + public func encode(to encoder: any Swift.Encoder) throws + public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@_Concurrency.MainActor public struct PaywallWebViewController { + @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) + @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessageAction { + public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) + @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension SwiftUICore.View { + @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View + +} @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onWebPurchaseRedemptionAttempt(perform completion: @escaping @Sendable (RevenueCat.WebPurchaseRedemptionResult) -> Swift.Void) -> some SwiftUICore.View @@ -279,5 +339,7 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-watchos.swiftinterface b/api/revenuecatui-api-watchos.swiftinterface index 39b2ed3084..0490cf9e59 100644 --- a/api/revenuecatui-api-watchos.swiftinterface +++ b/api/revenuecatui-api-watchos.swiftinterface @@ -166,6 +166,66 @@ open class CustomPaywallFontProvider : RevenueCatUI.PaywallFontProvider { @available(tvOS, unavailable, introduced: 15.0, message: "RevenueCatUI does not support tvOS yet") public typealias Body = @_opaqueReturnTypeOf("$s12RevenueCatUI11PaywallViewV4bodyQrvp", 0) __ } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { + public let componentID: Swift.String + public let type: Swift.String + public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? + public let error: Swift.String? + public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) + public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { + public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue + public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue + public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue + public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue + public static var null: RevenueCatUI.PaywallWebViewValue { + get + } + public var stringValue: Swift.String? { + get + } + public var numberValue: Swift.Double? { + get + } + public var boolValue: Swift.Bool? { + get + } + public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { + get + } + public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { + get + } + public var isNull: Swift.Bool { + get + } + public init(from decoder: any Swift.Decoder) throws + public func encode(to encoder: any Swift.Encoder) throws + public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@_Concurrency.MainActor public struct PaywallWebViewController { + @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) + @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +public struct PaywallWebViewMessageAction { + public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) + @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) +} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension SwiftUICore.View { + @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View + +} @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onWebPurchaseRedemptionAttempt(perform completion: @escaping @Sendable (RevenueCat.WebPurchaseRedemptionResult) -> Swift.Void) -> some SwiftUICore.View @@ -279,5 +339,7 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} From e67137891461869e80a0d07e2ff6b6d8bb071d6b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 16 Jul 2026 20:01:56 +0000 Subject: [PATCH 2/5] refactor(paywalls): keep web view bridge internal Co-authored-by: Jacob Rakidzich --- .../WebView/PaywallWebViewAPI.swift | 61 ++++++++------- .../AllAPITests.xcodeproj/project.pbxproj | 4 - .../PaywallWebViewAPI.swift | 77 ------------------- ...enuecatui-api-ios-simulator.swiftinterface | 62 --------------- api/revenuecatui-api-ios.swiftinterface | 62 --------------- api/revenuecatui-api-macos.swiftinterface | 62 --------------- ...atui-api-visionos-simulator.swiftinterface | 62 --------------- api/revenuecatui-api-visionos.swiftinterface | 62 --------------- ...catui-api-watchos-simulator.swiftinterface | 62 --------------- api/revenuecatui-api-watchos.swiftinterface | 62 --------------- 10 files changed, 30 insertions(+), 546 deletions(-) delete mode 100644 Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallWebViewAPI.swift diff --git a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift index 5ba2a3fe3b..4aed083814 100644 --- a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift +++ b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift @@ -1,26 +1,25 @@ import Foundation import SwiftUI -// swiftlint:disable missing_docs #if !os(tvOS) // For Paywalls V2 /// A validated message sent from a Paywalls V2 `web_view` component to your app. @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessage: Sendable, Equatable { +struct PaywallWebViewMessage: Sendable, Equatable { /// The identifier of the `web_view` component that produced this message. - public let componentID: String + let componentID: String /// The message type, e.g. `"rc:step-complete"`. - public let type: String + let type: String /// The responses collected by the web flow. Only populated for `"rc:step-complete"` messages. - public let responses: [String: PaywallWebViewValue]? + let responses: [String: PaywallWebViewValue]? /// The error reported by the web content. Only populated for `"rc:error"` messages. - public let error: String? + let error: String? - public init( + init( componentID: String, type: String, responses: [String: PaywallWebViewValue]? = nil, @@ -36,7 +35,7 @@ public struct PaywallWebViewMessage: Sendable, Equatable { /// A JSON-compatible value exchanged between a Paywalls V2 `web_view` component and your app. @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { +struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { private indirect enum Storage: Sendable, Equatable, Hashable { case string(String) @@ -54,54 +53,54 @@ public struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { } /// Creates a string value. - public static func string(_ value: String) -> Self { Self(.string(value)) } + static func string(_ value: String) -> Self { Self(.string(value)) } /// Creates a numeric value. Non-finite values normalize to ``null`` because JSON cannot encode them. - public static func number(_ value: Double) -> Self { value.isFinite ? Self(.number(value)) : .null } + static func number(_ value: Double) -> Self { value.isFinite ? Self(.number(value)) : .null } /// Creates a boolean value. - public static func bool(_ value: Bool) -> Self { Self(.bool(value)) } + static func bool(_ value: Bool) -> Self { Self(.bool(value)) } /// Creates an array value. - public static func array(_ value: [PaywallWebViewValue]) -> Self { Self(.array(value)) } + static func array(_ value: [PaywallWebViewValue]) -> Self { Self(.array(value)) } /// Creates an object (dictionary) value. - public static func object(_ value: [String: PaywallWebViewValue]) -> Self { Self(.object(value)) } + static func object(_ value: [String: PaywallWebViewValue]) -> Self { Self(.object(value)) } /// A null value. - public static var null: Self { Self(.null) } + static var null: Self { Self(.null) } - public var stringValue: String? { + var stringValue: String? { if case .string(let value) = self.storage { return value } return nil } - public var numberValue: Double? { + var numberValue: Double? { if case .number(let value) = self.storage { return value } return nil } - public var boolValue: Bool? { + var boolValue: Bool? { if case .bool(let value) = self.storage { return value } return nil } - public var arrayValue: [PaywallWebViewValue]? { + var arrayValue: [PaywallWebViewValue]? { if case .array(let value) = self.storage { return value } return nil } - public var objectValue: [String: PaywallWebViewValue]? { + var objectValue: [String: PaywallWebViewValue]? { if case .object(let value) = self.storage { return value } return nil } - public var isNull: Bool { + var isNull: Bool { if case .null = self.storage { return true } return false } - public init(from decoder: Decoder) throws { + init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() if container.decodeNil() { @@ -119,7 +118,7 @@ public struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { } } - public func encode(to encoder: Encoder) throws { + func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self.storage { @@ -142,34 +141,34 @@ public struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @MainActor -public struct PaywallWebViewController { +struct PaywallWebViewController { init() {} - public func postVariables(componentID: String, variables: [String: PaywallWebViewValue]) { - // Session wiring lands in a later PR; public API is inert until then. + func postVariables(componentID: String, variables: [String: PaywallWebViewValue]) { + // Session wiring lands in a later PR. } - public func postMessage(componentID: String, type: String, variables: [String: PaywallWebViewValue]) { - // Session wiring lands in a later PR; public API is inert until then. + func postMessage(componentID: String, type: String, variables: [String: PaywallWebViewValue]) { + // Session wiring lands in a later PR. } } /// A wrapper for the Paywalls V2 `web_view` message handler. @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessageAction { +struct PaywallWebViewMessageAction { private let action: @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void - public init( + init( _ action: @escaping @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void ) { self.action = action } @MainActor - public func callAsFunction(_ message: PaywallWebViewMessage, _ controller: PaywallWebViewController) { + func callAsFunction(_ message: PaywallWebViewMessage, _ controller: PaywallWebViewController) { self.action(message, controller) } @@ -194,7 +193,7 @@ extension EnvironmentValues { extension View { /// Invokes the given closure when a Paywalls V2 `web_view` component sends a message. - public func onPaywallWebViewMessage( + func onPaywallWebViewMessage( _ action: @escaping @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void ) -> some View { self.environment(\.paywallWebViewMessageAction, PaywallWebViewMessageAction(action)) diff --git a/Tests/APITesters/AllAPITests/AllAPITests.xcodeproj/project.pbxproj b/Tests/APITesters/AllAPITests/AllAPITests.xcodeproj/project.pbxproj index 74a25fd257..9cc8116989 100644 --- a/Tests/APITesters/AllAPITests/AllAPITests.xcodeproj/project.pbxproj +++ b/Tests/APITesters/AllAPITests/AllAPITests.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 1E8A60812CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E8A60802CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift */; }; - B096F58208E0AA6582F34133 /* PaywallWebViewAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0DC08831A62751743D823FA /* PaywallWebViewAPI.swift */; }; 1EB697C22CD26218003000FC /* WebPurchaseRedemptionResultAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EB697C12CD26218003000FC /* WebPurchaseRedemptionResultAPI.swift */; }; 2D4C60E12C5AD1BC00A29FD2 /* AllAPITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D4C60D82C5AD1BC00A29FD2 /* AllAPITests.framework */; }; 2D4C60E62C5AD1BC00A29FD2 /* AllAPITestsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4C60E52C5AD1BC00A29FD2 /* AllAPITestsTests.swift */; }; @@ -229,7 +228,6 @@ /* Begin PBXFileReference section */ 1E8A60802CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedeemWebPurchasesAPI.swift; sourceTree = ""; }; - B0DC08831A62751743D823FA /* PaywallWebViewAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallWebViewAPI.swift; sourceTree = ""; }; 1EB697C12CD26218003000FC /* WebPurchaseRedemptionResultAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebPurchaseRedemptionResultAPI.swift; sourceTree = ""; }; 2D4C60D82C5AD1BC00A29FD2 /* AllAPITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AllAPITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2D4C60DB2C5AD1BC00A29FD2 /* AllAPITests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AllAPITests.h; sourceTree = ""; }; @@ -647,7 +645,6 @@ children = ( FD33CD722D035876000D13A4 /* CustomerCenterViewControllerAPI.swift */, 2D4C622D2C5ADA6700A29FD2 /* PaywallViewAPI.swift */, - B0DC08831A62751743D823FA /* PaywallWebViewAPI.swift */, 1E8A60802CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift */, 2D4C622B2C5ADA6700A29FD2 /* PaywallViewControllerAPI.swift */, 2D4C622C2C5ADA6700A29FD2 /* main.swift */, @@ -1122,7 +1119,6 @@ FDCC983A2D0A0FD500F5854B /* CustomerCenterViewAPI.swift in Sources */, 2D4C62302C5ADA6700A29FD2 /* PaywallViewControllerAPI.swift in Sources */, 1E8A60812CDCF29D0034ACF3 /* RedeemWebPurchasesAPI.swift in Sources */, - B096F58208E0AA6582F34133 /* PaywallWebViewAPI.swift in Sources */, 2D4C622E2C5ADA6700A29FD2 /* PaywallViewAPI.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallWebViewAPI.swift b/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallWebViewAPI.swift deleted file mode 100644 index a8a2986ca9..0000000000 --- a/Tests/APITesters/AllAPITests/RevenueCatUISwiftAPITester/PaywallWebViewAPI.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// PaywallWebViewAPI.swift -// RevenueCatUISwiftAPITester -// -// Compile-time checks for the Paywalls V2 web_view public API surface. -// - -import RevenueCat -import RevenueCatUI -import SwiftUI - -#if !os(tvOS) // For Paywalls V2 - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -struct PaywallWebViewApp: View { - - var body: some View { - Text("") - .onPaywallWebViewMessage { (message: PaywallWebViewMessage, controller: PaywallWebViewController) in - let componentID: String = message.componentID - let type: String = message.type - let responses: [String: PaywallWebViewValue]? = message.responses - let error: String? = message.error - - controller.postVariables( - componentID: componentID, - variables: ["custom": .object(["plan": .string("annual")])] - ) - controller.postMessage(componentID: componentID, type: type, variables: [:]) - - _ = (responses, error) - } - } - -} - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -func checkPaywallWebViewMessageAPI() { - let message = PaywallWebViewMessage( - componentID: "", - type: "rc:step-complete", - responses: ["selected_plan": .string("annual")], - error: nil - ) - let sameMessage: Bool = message == message - _ = sameMessage -} - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -func checkPaywallWebViewValueAPI() { - let string: PaywallWebViewValue = .string("s") - let number: PaywallWebViewValue = .number(1.5) - let bool: PaywallWebViewValue = .bool(true) - let array: PaywallWebViewValue = .array([string, number]) - let object: PaywallWebViewValue = .object(["key": bool]) - let null: PaywallWebViewValue = .null - - let _: String? = string.stringValue - let _: Double? = number.numberValue - let _: Bool? = bool.boolValue - let _: [PaywallWebViewValue]? = array.arrayValue - let _: [String: PaywallWebViewValue]? = object.objectValue - let _: Bool = null.isNull - let _: Set = [string, number] -} - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@MainActor -func checkPaywallWebViewMessageActionAPI( - message: PaywallWebViewMessage, - controller: PaywallWebViewController -) { - let action = PaywallWebViewMessageAction { (_: PaywallWebViewMessage, _: PaywallWebViewController) in } - action(message, controller) -} - -#endif diff --git a/api/revenuecatui-api-ios-simulator.swiftinterface b/api/revenuecatui-api-ios-simulator.swiftinterface index 428cfba3b0..30bbb7549c 100644 --- a/api/revenuecatui-api-ios-simulator.swiftinterface +++ b/api/revenuecatui-api-ios-simulator.swiftinterface @@ -309,66 +309,6 @@ extension RevenueCat.Purchases { @available(iOS 15.0, macOS 12.0, *) @_Concurrency.MainActor @objc final public func presentPaywall(from url: Foundation.URL) -> Swift.Bool } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { - public let componentID: Swift.String - public let type: Swift.String - public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? - public let error: Swift.String? - public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) - public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { - public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue - public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue - public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue - public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static var null: RevenueCatUI.PaywallWebViewValue { - get - } - public var stringValue: Swift.String? { - get - } - public var numberValue: Swift.Double? { - get - } - public var boolValue: Swift.Bool? { - get - } - public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { - get - } - public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { - get - } - public var isNull: Swift.Bool { - get - } - public init(from decoder: any Swift.Decoder) throws - public func encode(to encoder: any Swift.Encoder) throws - public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@_Concurrency.MainActor public struct PaywallWebViewController { - @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) - @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessageAction { - public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) - @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension SwiftUICore.View { - @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View - -} @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) @objc(RCPaywallFooterViewController) @_Concurrency.MainActor @preconcurrency final public class PaywallFooterViewController : RevenueCatUI.PaywallViewController { @_Concurrency.MainActor @preconcurrency public init(offering: RevenueCat.Offering? = nil, performPurchase: @escaping RevenueCatUI.PerformPurchase, performRestore: @escaping RevenueCatUI.PerformRestore, dismissRequestedHandler: ((_ controller: RevenueCatUI.PaywallViewController) -> Swift.Void)? = nil) @@ -606,7 +546,5 @@ extension RevenueCatUI.CustomerCenterNavigationLink : Swift.Sendable {} @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-ios.swiftinterface b/api/revenuecatui-api-ios.swiftinterface index 9514729189..5106fe465c 100644 --- a/api/revenuecatui-api-ios.swiftinterface +++ b/api/revenuecatui-api-ios.swiftinterface @@ -309,66 +309,6 @@ extension RevenueCat.Purchases { @available(iOS 15.0, macOS 12.0, *) @_Concurrency.MainActor @objc final public func presentPaywall(from url: Foundation.URL) -> Swift.Bool } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { - public let componentID: Swift.String - public let type: Swift.String - public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? - public let error: Swift.String? - public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) - public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { - public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue - public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue - public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue - public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static var null: RevenueCatUI.PaywallWebViewValue { - get - } - public var stringValue: Swift.String? { - get - } - public var numberValue: Swift.Double? { - get - } - public var boolValue: Swift.Bool? { - get - } - public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { - get - } - public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { - get - } - public var isNull: Swift.Bool { - get - } - public init(from decoder: any Swift.Decoder) throws - public func encode(to encoder: any Swift.Encoder) throws - public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@_Concurrency.MainActor public struct PaywallWebViewController { - @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) - @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessageAction { - public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) - @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension SwiftUICore.View { - @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View - -} @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) @objc(RCPaywallFooterViewController) @_Concurrency.MainActor @preconcurrency final public class PaywallFooterViewController : RevenueCatUI.PaywallViewController { @_Concurrency.MainActor @preconcurrency public init(offering: RevenueCat.Offering? = nil, performPurchase: @escaping RevenueCatUI.PerformPurchase, performRestore: @escaping RevenueCatUI.PerformRestore, dismissRequestedHandler: ((_ controller: RevenueCatUI.PaywallViewController) -> Swift.Void)? = nil) @@ -606,7 +546,5 @@ extension RevenueCatUI.CustomerCenterNavigationLink : Swift.Sendable {} @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-macos.swiftinterface b/api/revenuecatui-api-macos.swiftinterface index d7553c3e37..e64db71c52 100644 --- a/api/revenuecatui-api-macos.swiftinterface +++ b/api/revenuecatui-api-macos.swiftinterface @@ -168,66 +168,6 @@ open class CustomPaywallFontProvider : RevenueCatUI.PaywallFontProvider { @available(tvOS, unavailable, introduced: 15.0, message: "RevenueCatUI does not support tvOS yet") public typealias Body = @_opaqueReturnTypeOf("$s12RevenueCatUI11PaywallViewV4bodyQrvp", 0) __ } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { - public let componentID: Swift.String - public let type: Swift.String - public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? - public let error: Swift.String? - public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) - public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { - public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue - public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue - public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue - public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static var null: RevenueCatUI.PaywallWebViewValue { - get - } - public var stringValue: Swift.String? { - get - } - public var numberValue: Swift.Double? { - get - } - public var boolValue: Swift.Bool? { - get - } - public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { - get - } - public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { - get - } - public var isNull: Swift.Bool { - get - } - public init(from decoder: any Swift.Decoder) throws - public func encode(to encoder: any Swift.Encoder) throws - public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@_Concurrency.MainActor public struct PaywallWebViewController { - @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) - @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessageAction { - public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) - @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension SwiftUICore.View { - @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View - -} @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onWebPurchaseRedemptionAttempt(perform completion: @escaping @Sendable (RevenueCat.WebPurchaseRedemptionResult) -> Swift.Void) -> some SwiftUICore.View @@ -384,7 +324,5 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-visionos-simulator.swiftinterface b/api/revenuecatui-api-visionos-simulator.swiftinterface index 7369428ec5..b87d2b82d9 100644 --- a/api/revenuecatui-api-visionos-simulator.swiftinterface +++ b/api/revenuecatui-api-visionos-simulator.swiftinterface @@ -179,66 +179,6 @@ extension RevenueCat.Purchases { @available(iOS 15.0, macOS 12.0, *) @_Concurrency.MainActor @objc final public func presentPaywall(from url: Foundation.URL) -> Swift.Bool } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { - public let componentID: Swift.String - public let type: Swift.String - public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? - public let error: Swift.String? - public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) - public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { - public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue - public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue - public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue - public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static var null: RevenueCatUI.PaywallWebViewValue { - get - } - public var stringValue: Swift.String? { - get - } - public var numberValue: Swift.Double? { - get - } - public var boolValue: Swift.Bool? { - get - } - public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { - get - } - public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { - get - } - public var isNull: Swift.Bool { - get - } - public init(from decoder: any Swift.Decoder) throws - public func encode(to encoder: any Swift.Encoder) throws - public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@_Concurrency.MainActor public struct PaywallWebViewController { - @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) - @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessageAction { - public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) - @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension SwiftUICore.View { - @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View - -} @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) @objc(RCPaywallFooterViewController) @_Concurrency.MainActor @preconcurrency final public class PaywallFooterViewController : RevenueCatUI.PaywallViewController { @_Concurrency.MainActor @preconcurrency public init(offering: RevenueCat.Offering? = nil, performPurchase: @escaping RevenueCatUI.PerformPurchase, performRestore: @escaping RevenueCatUI.PerformRestore, dismissRequestedHandler: ((_ controller: RevenueCatUI.PaywallViewController) -> Swift.Void)? = nil) @@ -466,7 +406,5 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-visionos.swiftinterface b/api/revenuecatui-api-visionos.swiftinterface index cccba66c64..ec8d35ca1f 100644 --- a/api/revenuecatui-api-visionos.swiftinterface +++ b/api/revenuecatui-api-visionos.swiftinterface @@ -179,66 +179,6 @@ extension RevenueCat.Purchases { @available(iOS 15.0, macOS 12.0, *) @_Concurrency.MainActor @objc final public func presentPaywall(from url: Foundation.URL) -> Swift.Bool } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { - public let componentID: Swift.String - public let type: Swift.String - public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? - public let error: Swift.String? - public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) - public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { - public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue - public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue - public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue - public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static var null: RevenueCatUI.PaywallWebViewValue { - get - } - public var stringValue: Swift.String? { - get - } - public var numberValue: Swift.Double? { - get - } - public var boolValue: Swift.Bool? { - get - } - public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { - get - } - public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { - get - } - public var isNull: Swift.Bool { - get - } - public init(from decoder: any Swift.Decoder) throws - public func encode(to encoder: any Swift.Encoder) throws - public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@_Concurrency.MainActor public struct PaywallWebViewController { - @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) - @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessageAction { - public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) - @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension SwiftUICore.View { - @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View - -} @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) @objc(RCPaywallFooterViewController) @_Concurrency.MainActor @preconcurrency final public class PaywallFooterViewController : RevenueCatUI.PaywallViewController { @_Concurrency.MainActor @preconcurrency public init(offering: RevenueCat.Offering? = nil, performPurchase: @escaping RevenueCatUI.PerformPurchase, performRestore: @escaping RevenueCatUI.PerformRestore, dismissRequestedHandler: ((_ controller: RevenueCatUI.PaywallViewController) -> Swift.Void)? = nil) @@ -466,7 +406,5 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-watchos-simulator.swiftinterface b/api/revenuecatui-api-watchos-simulator.swiftinterface index 7038282c5d..03d128c761 100644 --- a/api/revenuecatui-api-watchos-simulator.swiftinterface +++ b/api/revenuecatui-api-watchos-simulator.swiftinterface @@ -166,66 +166,6 @@ open class CustomPaywallFontProvider : RevenueCatUI.PaywallFontProvider { @available(tvOS, unavailable, introduced: 15.0, message: "RevenueCatUI does not support tvOS yet") public typealias Body = @_opaqueReturnTypeOf("$s12RevenueCatUI11PaywallViewV4bodyQrvp", 0) __ } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { - public let componentID: Swift.String - public let type: Swift.String - public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? - public let error: Swift.String? - public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) - public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { - public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue - public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue - public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue - public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static var null: RevenueCatUI.PaywallWebViewValue { - get - } - public var stringValue: Swift.String? { - get - } - public var numberValue: Swift.Double? { - get - } - public var boolValue: Swift.Bool? { - get - } - public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { - get - } - public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { - get - } - public var isNull: Swift.Bool { - get - } - public init(from decoder: any Swift.Decoder) throws - public func encode(to encoder: any Swift.Encoder) throws - public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@_Concurrency.MainActor public struct PaywallWebViewController { - @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) - @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessageAction { - public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) - @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension SwiftUICore.View { - @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View - -} @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onWebPurchaseRedemptionAttempt(perform completion: @escaping @Sendable (RevenueCat.WebPurchaseRedemptionResult) -> Swift.Void) -> some SwiftUICore.View @@ -339,7 +279,5 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} diff --git a/api/revenuecatui-api-watchos.swiftinterface b/api/revenuecatui-api-watchos.swiftinterface index 0490cf9e59..39b2ed3084 100644 --- a/api/revenuecatui-api-watchos.swiftinterface +++ b/api/revenuecatui-api-watchos.swiftinterface @@ -166,66 +166,6 @@ open class CustomPaywallFontProvider : RevenueCatUI.PaywallFontProvider { @available(tvOS, unavailable, introduced: 15.0, message: "RevenueCatUI does not support tvOS yet") public typealias Body = @_opaqueReturnTypeOf("$s12RevenueCatUI11PaywallViewV4bodyQrvp", 0) __ } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessage : Swift.Sendable, Swift.Equatable { - public let componentID: Swift.String - public let type: Swift.String - public let responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? - public let error: Swift.String? - public init(componentID: Swift.String, type: Swift.String, responses: [Swift.String : RevenueCatUI.PaywallWebViewValue]? = nil, error: Swift.String? = nil) - public static func == (a: RevenueCatUI.PaywallWebViewMessage, b: RevenueCatUI.PaywallWebViewMessage) -> Swift.Bool -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewValue : Swift.Sendable, Swift.Equatable, Swift.Hashable, Swift.Codable { - public static func string(_ value: Swift.String) -> RevenueCatUI.PaywallWebViewValue - public static func number(_ value: Swift.Double) -> RevenueCatUI.PaywallWebViewValue - public static func bool(_ value: Swift.Bool) -> RevenueCatUI.PaywallWebViewValue - public static func array(_ value: [RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static func object(_ value: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -> RevenueCatUI.PaywallWebViewValue - public static var null: RevenueCatUI.PaywallWebViewValue { - get - } - public var stringValue: Swift.String? { - get - } - public var numberValue: Swift.Double? { - get - } - public var boolValue: Swift.Bool? { - get - } - public var arrayValue: [RevenueCatUI.PaywallWebViewValue]? { - get - } - public var objectValue: [Swift.String : RevenueCatUI.PaywallWebViewValue]? { - get - } - public var isNull: Swift.Bool { - get - } - public init(from decoder: any Swift.Decoder) throws - public func encode(to encoder: any Swift.Encoder) throws - public static func == (a: RevenueCatUI.PaywallWebViewValue, b: RevenueCatUI.PaywallWebViewValue) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@_Concurrency.MainActor public struct PaywallWebViewController { - @_Concurrency.MainActor public func postVariables(componentID: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) - @_Concurrency.MainActor public func postMessage(componentID: Swift.String, type: Swift.String, variables: [Swift.String : RevenueCatUI.PaywallWebViewValue]) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public struct PaywallWebViewMessageAction { - public init(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) - @_Concurrency.MainActor public func callAsFunction(_ message: RevenueCatUI.PaywallWebViewMessage, _ controller: RevenueCatUI.PaywallWebViewController) -} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension SwiftUICore.View { - @_Concurrency.MainActor @preconcurrency public func onPaywallWebViewMessage(_ action: @escaping @_Concurrency.MainActor (RevenueCatUI.PaywallWebViewMessage, RevenueCatUI.PaywallWebViewController) -> Swift.Void) -> some SwiftUICore.View - -} @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension SwiftUICore.View { @_Concurrency.MainActor @preconcurrency public func onWebPurchaseRedemptionAttempt(perform completion: @escaping @Sendable (RevenueCat.WebPurchaseRedemptionResult) -> Swift.Void) -> some SwiftUICore.View @@ -339,7 +279,5 @@ extension SwiftUICore.View { @available(iOS 15.0, macOS 12.0, watchOS 8.0, *) @available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet") extension RevenueCatUI.PaywallView : Swift.Sendable {} -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension RevenueCatUI.PaywallWebViewController : Swift.Sendable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Equatable {} extension RevenueCatUI.PaywallPresentationMode : Swift.Hashable {} From 06125950309f465a64383feeb5b73fab4ba3703a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 14:45:14 +0000 Subject: [PATCH 3/5] refactor(paywalls): remove unused web view handler API Co-authored-by: Jacob Rakidzich --- .../WebView/PaywallWebViewAPI.swift | 96 +------------------ 1 file changed, 2 insertions(+), 94 deletions(-) diff --git a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift index 4aed083814..25e0d16a6c 100644 --- a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift +++ b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift @@ -1,44 +1,14 @@ import Foundation -import SwiftUI #if !os(tvOS) // For Paywalls V2 -/// A validated message sent from a Paywalls V2 `web_view` component to your app. -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -struct PaywallWebViewMessage: Sendable, Equatable { - - /// The identifier of the `web_view` component that produced this message. - let componentID: String - - /// The message type, e.g. `"rc:step-complete"`. - let type: String - - /// The responses collected by the web flow. Only populated for `"rc:step-complete"` messages. - let responses: [String: PaywallWebViewValue]? - - /// The error reported by the web content. Only populated for `"rc:error"` messages. - let error: String? - - init( - componentID: String, - type: String, - responses: [String: PaywallWebViewValue]? = nil, - error: String? = nil - ) { - self.componentID = componentID - self.type = type - self.responses = responses - self.error = error - } - -} - /// A JSON-compatible value exchanged between a Paywalls V2 `web_view` component and your app. @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { - private indirect enum Storage: Sendable, Equatable, Hashable { + private enum Storage: Sendable, Equatable, Hashable { case string(String) + // The web peer uses JavaScript `Number` values, so there is no integer precision to preserve. case number(Double) case bool(Bool) case array([PaywallWebViewValue]) @@ -139,66 +109,4 @@ struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@MainActor -struct PaywallWebViewController { - - init() {} - - func postVariables(componentID: String, variables: [String: PaywallWebViewValue]) { - // Session wiring lands in a later PR. - } - - func postMessage(componentID: String, type: String, variables: [String: PaywallWebViewValue]) { - // Session wiring lands in a later PR. - } - -} - -/// A wrapper for the Paywalls V2 `web_view` message handler. -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -struct PaywallWebViewMessageAction { - - private let action: @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void - - init( - _ action: @escaping @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void - ) { - self.action = action - } - - @MainActor - func callAsFunction(_ message: PaywallWebViewMessage, _ controller: PaywallWebViewController) { - self.action(message, controller) - } - -} - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -struct PaywallWebViewMessageActionKey: EnvironmentKey { - static let defaultValue: PaywallWebViewMessageAction? = nil -} - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension EnvironmentValues { - - var paywallWebViewMessageAction: PaywallWebViewMessageAction? { - get { self[PaywallWebViewMessageActionKey.self] } - set { self[PaywallWebViewMessageActionKey.self] = newValue } - } - -} - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension View { - - /// Invokes the given closure when a Paywalls V2 `web_view` component sends a message. - func onPaywallWebViewMessage( - _ action: @escaping @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void - ) -> some View { - self.environment(\.paywallWebViewMessageAction, PaywallWebViewMessageAction(action)) - } - -} - #endif From d14d63ca685f5932e3b031f700a11ccde72cef16 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 14:46:22 +0000 Subject: [PATCH 4/5] fix(paywalls): retain internal bridge dependencies Co-authored-by: Jacob Rakidzich --- .../WebView/PaywallWebViewAPI.swift | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift index 25e0d16a6c..145b578a94 100644 --- a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift +++ b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift @@ -1,7 +1,38 @@ import Foundation +import SwiftUI #if !os(tvOS) // For Paywalls V2 +/// A validated message sent from a Paywalls V2 `web_view` component to your app. +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +struct PaywallWebViewMessage: Sendable, Equatable { + + /// The identifier of the `web_view` component that produced this message. + let componentID: String + + /// The message type, e.g. `"rc:step-complete"`. + let type: String + + /// The responses collected by the web flow. Only populated for `"rc:step-complete"` messages. + let responses: [String: PaywallWebViewValue]? + + /// The error reported by the web content. Only populated for `"rc:error"` messages. + let error: String? + + init( + componentID: String, + type: String, + responses: [String: PaywallWebViewValue]? = nil, + error: String? = nil + ) { + self.componentID = componentID + self.type = type + self.responses = responses + self.error = error + } + +} + /// A JSON-compatible value exchanged between a Paywalls V2 `web_view` component and your app. @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { @@ -109,4 +140,54 @@ struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +@MainActor +struct PaywallWebViewController { + + init() {} + + func postVariables(componentID: String, variables: [String: PaywallWebViewValue]) { + // Session wiring lands in a later PR. + } + + func postMessage(componentID: String, type: String, variables: [String: PaywallWebViewValue]) { + // Session wiring lands in a later PR. + } + +} + +/// A wrapper for the Paywalls V2 `web_view` message handler. +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +struct PaywallWebViewMessageAction { + + private let action: @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void + + init( + _ action: @escaping @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void + ) { + self.action = action + } + + @MainActor + func callAsFunction(_ message: PaywallWebViewMessage, _ controller: PaywallWebViewController) { + self.action(message, controller) + } + +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +struct PaywallWebViewMessageActionKey: EnvironmentKey { + static let defaultValue: PaywallWebViewMessageAction? = nil +} + +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) +extension EnvironmentValues { + + var paywallWebViewMessageAction: PaywallWebViewMessageAction? { + get { self[PaywallWebViewMessageActionKey.self] } + set { self[PaywallWebViewMessageActionKey.self] = newValue } + } + +} + #endif From 19cbfe67e290fc2c676da40fb99c58e53320ac1a Mon Sep 17 00:00:00 2001 From: Jacob Rakidzich Date: Fri, 17 Jul 2026 11:09:28 -0500 Subject: [PATCH 5/5] refactor(paywalls): remove web view message handler concept The bridge no longer forwards messages to an app-provided handler, so the message, action, controller, and environment types are removed. Only the JSON value type remains. Co-authored-by: Cursor --- .../WebView/PaywallWebViewAPI.swift | 81 ------------------- 1 file changed, 81 deletions(-) diff --git a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift index 145b578a94..25e0d16a6c 100644 --- a/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift +++ b/RevenueCatUI/Templates/V2/Components/WebView/PaywallWebViewAPI.swift @@ -1,38 +1,7 @@ import Foundation -import SwiftUI #if !os(tvOS) // For Paywalls V2 -/// A validated message sent from a Paywalls V2 `web_view` component to your app. -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -struct PaywallWebViewMessage: Sendable, Equatable { - - /// The identifier of the `web_view` component that produced this message. - let componentID: String - - /// The message type, e.g. `"rc:step-complete"`. - let type: String - - /// The responses collected by the web flow. Only populated for `"rc:step-complete"` messages. - let responses: [String: PaywallWebViewValue]? - - /// The error reported by the web content. Only populated for `"rc:error"` messages. - let error: String? - - init( - componentID: String, - type: String, - responses: [String: PaywallWebViewValue]? = nil, - error: String? = nil - ) { - self.componentID = componentID - self.type = type - self.responses = responses - self.error = error - } - -} - /// A JSON-compatible value exchanged between a Paywalls V2 `web_view` component and your app. @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { @@ -140,54 +109,4 @@ struct PaywallWebViewValue: Sendable, Equatable, Hashable, Codable { } -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -@MainActor -struct PaywallWebViewController { - - init() {} - - func postVariables(componentID: String, variables: [String: PaywallWebViewValue]) { - // Session wiring lands in a later PR. - } - - func postMessage(componentID: String, type: String, variables: [String: PaywallWebViewValue]) { - // Session wiring lands in a later PR. - } - -} - -/// A wrapper for the Paywalls V2 `web_view` message handler. -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -struct PaywallWebViewMessageAction { - - private let action: @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void - - init( - _ action: @escaping @MainActor (PaywallWebViewMessage, PaywallWebViewController) -> Void - ) { - self.action = action - } - - @MainActor - func callAsFunction(_ message: PaywallWebViewMessage, _ controller: PaywallWebViewController) { - self.action(message, controller) - } - -} - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -struct PaywallWebViewMessageActionKey: EnvironmentKey { - static let defaultValue: PaywallWebViewMessageAction? = nil -} - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension EnvironmentValues { - - var paywallWebViewMessageAction: PaywallWebViewMessageAction? { - get { self[PaywallWebViewMessageActionKey.self] } - set { self[PaywallWebViewMessageActionKey.self] = newValue } - } - -} - #endif