Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

The changelog for `SuperwallKit`. Also see the [releases](https://github.com/superwall/Superwall-iOS/releases) on GitHub.

## 4.14.2

### Enhancements

- Adds multipage paywall navigation tracking by tracking a `paywall_page_view` event, which contains information about the page view.

## 4.14.1

### Enhancements
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,39 @@ enum InternalSuperwallEvent {
}
}

struct PaywallPageView: TrackableSuperwallEvent {
var superwallEvent: SuperwallEvent {
return .paywallPageView(
paywallInfo: paywallInfo,
data: data
)
}
let paywallInfo: PaywallInfo
let data: PageViewData

func getSuperwallParameters() async -> [String: Any] {
var params = await paywallInfo.placementParams()
params["page_node_id"] = data.pageNodeId
params["flow_position"] = data.flowPosition
params["page_name"] = data.pageName
params["navigation_node_id"] = data.navigationNodeId
params["navigation_type"] = data.navigationType
if let previousPageNodeId = data.previousPageNodeId {
params["previous_page_node_id"] = previousPageNodeId
}
if let previousFlowPosition = data.previousFlowPosition {
params["previous_flow_position"] = previousFlowPosition
}
if let timeOnPreviousPageMs = data.timeOnPreviousPageMs {
params["time_on_previous_page_ms"] = timeOnPreviousPageMs
}
return params
}
var audienceFilterParams: [String: Any] {
return paywallInfo.audienceFilterParams()
}
}

struct PaywallClose: TrackableSuperwallEvent {
var superwallEvent: SuperwallEvent {
return .paywallClose(paywallInfo: paywallInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@ public enum SuperwallEvent {
/// When the test mode modal is closed.
case testModeModalClose

/// When a user navigates to a page in a multi-page paywall.
case paywallPageView(
paywallInfo: PaywallInfo,
data: PageViewData
)

var canImplicitlyTriggerPaywall: Bool {
switch self {
case .appInstall,
Expand Down Expand Up @@ -478,6 +484,8 @@ extension SuperwallEvent {
return .init(objcEvent: .testModeModalOpen)
case .testModeModalClose:
return .init(objcEvent: .testModeModalClose)
case .paywallPageView:
return .init(objcEvent: .paywallPageView)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ public enum SuperwallEventObjc: Int, CaseIterable {
/// When the test mode modal is closed.
case testModeModalClose

/// When a user navigates to a page in a multi-page paywall.
case paywallPageView

public init(event: SuperwallEvent) {
self = event.backingData.objcEvent
}
Expand Down Expand Up @@ -419,6 +422,8 @@ public enum SuperwallEventObjc: Int, CaseIterable {
return "testModeModal_open"
case .testModeModalClose:
return "testModeModal_close"
case .paywallPageView:
return "paywall_page_view"
}
}
}
2 changes: 1 addition & 1 deletion Sources/SuperwallKit/Misc/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ let sdkVersion = """
*/

let sdkVersion = """
4.14.1
4.14.2
"""
6 changes: 6 additions & 0 deletions Sources/SuperwallKit/Models/Paywall/Paywall.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ struct Paywall: Codable {

// MARK: - Added by client

/// A unique identifier for this paywall presentation, used to correlate all events
/// within a single presentation lifecycle.
var presentationId: String?

var responseLoadingInfo: LoadingInfo
var webviewLoadingInfo: LoadingInfo
var shimmerLoadingInfo: LoadingInfo
Expand Down Expand Up @@ -424,6 +428,7 @@ struct Paywall: Codable {
url: url,
products: products,
productIds: productIds,
presentationId: presentationId,
fromPlacementData: fromPlacement,
responseLoadStartTime: responseLoadingInfo.startAt,
responseLoadCompleteTime: responseLoadingInfo.endAt,
Expand Down Expand Up @@ -460,6 +465,7 @@ struct Paywall: Codable {
presentationSourceType = paywall.presentationSourceType
experiment = paywall.experiment
featureGating = paywall.featureGating
presentationId = paywall.presentationId
}
}

Expand Down
11 changes: 10 additions & 1 deletion Sources/SuperwallKit/Paywall/Presentation/PaywallInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ public final class PaywallInfo: NSObject {
/// `.automatic`.
public let introOfferEligibility: IntroOfferEligibility

/// A unique identifier for this paywall presentation, used to correlate all events
/// within a single presentation lifecycle.
public let presentationId: String?

init(
databaseId: String,
identifier: String,
Expand All @@ -144,6 +148,7 @@ public final class PaywallInfo: NSObject {
url: URL,
products: [Product],
productIds: [String],
presentationId: String?,
fromPlacementData placementData: PlacementData?,
responseLoadStartTime: Date?,
responseLoadCompleteTime: Date?,
Expand Down Expand Up @@ -182,6 +187,7 @@ public final class PaywallInfo: NSObject {
self.presentationSourceType = presentationSourceType
self.experiment = experiment
self.paywalljsVersion = paywalljsVersion
self.presentationId = presentationId
self.products = products
self.productIds = productIds
self.isFreeTrialAvailable = isFreeTrialAvailable
Expand Down Expand Up @@ -271,7 +277,8 @@ public final class PaywallInfo: NSObject {
"close_reason": closeReason.description,
"is_scroll_enabled": isScrollEnabled as Any,
"intro_offer_eligibility": introOfferEligibility.description,
"app_transaction_id": ReceiptManager.appTransactionId as Any
"app_transaction_id": ReceiptManager.appTransactionId as Any,
"presentation_id": presentationId as Any
]

var loadingVars: [String: Any] = [:]
Expand Down Expand Up @@ -356,6 +363,7 @@ extension PaywallInfo: Stubbable {
url: URL(string: "https://superwall.com")!,
products: [],
productIds: [],
presentationId: nil,
fromPlacementData: nil,
responseLoadStartTime: nil,
responseLoadCompleteTime: nil,
Expand Down Expand Up @@ -398,6 +406,7 @@ extension PaywallInfo: Stubbable {
url: URL(string: "https://superwall.com")!,
products: [],
productIds: [],
presentationId: nil,
fromPlacementData: nil,
responseLoadStartTime: nil,
responseLoadCompleteTime: nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ extension PaywallRequestManager {
paywallId: request.responseIdentifiers.paywallId,
placement: request.placementData
)
let paywall = try await getPaywallResponse(from: request)
var paywall = try await getPaywallResponse(from: request)
paywall.presentationId = UUID().uuidString

let paywallInfo = paywall.getInfo(fromPlacement: request.placementData)
await trackResponseLoaded(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// PageViewData.swift
//
//
// Created by Yusuf Tör on 16/03/2026.
//

import Foundation

/// Contains page-specific details for a multi-page paywall page view.
public struct PageViewData: Decodable, Equatable {
/// The unique identifier for the page node.
public let pageNodeId: String

/// The zero-based index of the page in the paywall flow.
public let flowPosition: Int

/// The display name of the page.
public let pageName: String

/// The unique identifier for the navigation node.
public let navigationNodeId: String

/// The unique identifier for the previous page node, if any.
public let previousPageNodeId: String?

/// The flow position of the previous page, if any.
public let previousFlowPosition: Int?

/// How the user navigated to the page. Possible values:
/// `"entry"`, `"forward"`, `"back"`, `"auto_transition"`.
public let navigationType: String

/// Time spent on the previous page in milliseconds, if any.
public let timeOnPreviousPageMs: Int?

private enum CodingKeys: String, CodingKey {
case pageNodeId
case flowPosition
case pageName
case navigationNodeId
case previousPageNodeId
case previousFlowPosition
case navigationType = "type"
case timeOnPreviousPageMs
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ enum PaywallMessage: Decodable, Equatable {
variables: JSON?
)
case hapticFeedback(hapticType: String)
case pageView(PageViewData)

// All cases below here are sent from device to paywall
case paywallClose
Expand Down Expand Up @@ -121,6 +122,7 @@ enum PaywallMessage: Decodable, Equatable {
case requestPermission = "request_permission"
case requestCallback = "request_callback"
case hapticFeedback = "haptic_feedback"
case pageView = "page_view"
}

// Everyone write to eventName, other may use the remaining keys
Expand Down Expand Up @@ -310,6 +312,11 @@ enum PaywallMessage: Decodable, Equatable {
self = .hapticFeedback(hapticType: hapticType)
return
}
case .pageView:
if let data = try? PageViewData(from: decoder) {
self = .pageView(data)
return
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,16 @@
)
case .hapticFeedback(let hapticType):
triggerHapticFeedback(hapticType)
case .pageView(let data):
guard let delegate = delegate else { return }
let paywallInfo = delegate.info
Task {
let event = InternalSuperwallEvent.PaywallPageView(
paywallInfo: paywallInfo,
data: data
)
await Superwall.shared.track(event)
}
}
}

Expand Down Expand Up @@ -414,7 +424,7 @@
// block selection
let selectionString =
// swiftlint:disable:next line_length
"var css = '*{-webkit-touch-callout:none;-webkit-user-select:none} .w-webflow-badge { display: none !important; }'; "

Check warning on line 427 in Sources/SuperwallKit/Paywall/View Controller/Web View/Message Handling/PaywallMessageHandler.swift

View workflow job for this annotation

GitHub Actions / Package-SwiftLint

Superfluous Disable Command Violation: SwiftLint rule 'line_length' did not trigger a violation in the disabled region; remove the disable command (superfluous_disable_command)
+ "var head = document.head || document.getElementsByTagName('head')[0]; "
+ "var style = document.createElement('style'); style.type = 'text/css'; "
+ "style.appendChild(document.createTextNode(css)); head.appendChild(style); "
Expand Down
2 changes: 1 addition & 1 deletion SuperwallKit.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "SuperwallKit"
s.version = "4.14.1"
s.version = "4.14.2"
s.summary = "Superwall: In-App Paywalls Made Easy"
s.description = "Paywall infrastructure for mobile apps :) we make things like editing your paywall and running price tests as easy as clicking a few buttons. superwall.com"

Expand Down
12 changes: 12 additions & 0 deletions SuperwallKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
342593FCA24FBEA77FE472C7 /* SK2ReceiptManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 050BC76657949DBB5F3D551C /* SK2ReceiptManager.swift */; };
3464196F9088F8A320FE24A4 /* PendingStripeCheckoutPollState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797EC0356AA1065ED11835BF /* PendingStripeCheckoutPollState.swift */; };
35597883CB038DBEE63E162B /* EventData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86D76FB5809C3B8122778A9 /* EventData.swift */; };
3652D5EE4C172D623BDEE7E4 /* PresentationIdTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3F306D67A9F3A43D082DD83 /* PresentationIdTests.swift */; };
369677E9A6E8754CFD20714D /* TrackingParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 764012CF0C0972240A73E3CF /* TrackingParameters.swift */; };
36B598D26A38D50CC713FD73 /* ProductsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 641BC3C3F8AC2D6E1EF44D55 /* ProductsManager.swift */; };
37264FFAF68B8349BD6F9BE8 /* WebEntitlementRedeemerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2D8F44D23EDD6316E1C4EE1 /* WebEntitlementRedeemerTests.swift */; };
Expand Down Expand Up @@ -264,12 +265,14 @@
7F630637D79A1F24CC17A8A5 /* GetPaywallVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB9AEAF72391341B4BDF6CD /* GetPaywallVC.swift */; };
7FCDAF6C945FA04FC4C4E8E3 /* DeviceHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB242DC77FEC0BE10C0DDC9C /* DeviceHelper.swift */; };
803BFA630F96B638E3BDE715 /* GameControllerEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C52F36F0BFF59363EBB4C7 /* GameControllerEvent.swift */; };
80A96673A17176DD5EFE1FA5 /* PageViewMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB7C70BFD23FD038393FD6DC /* PageViewMessageTests.swift */; };
81680E02D1693BF58E015C0C /* ASN1Decoder+UnkeyedDecodingContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D31BB6D0C57337C6E929D617 /* ASN1Decoder+UnkeyedDecodingContainer.swift */; };
822B2898CDD9C6E50816F62B /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD9298A79020030E9A1357A6 /* API.swift */; };
84616856D40F775122FD9BF9 /* Dictionary+Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 571825E7515FCC1E877D4429 /* Dictionary+Cache.swift */; };
847E0BD4BDA515E47608F6A1 /* ProductsFetcherSK2Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECD75DF8F3EB6A68A21444D /* ProductsFetcherSK2Tests.swift */; };
85728EABBC5C73193AC5F876 /* CustomURLSessionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3506FCC35155DF104A1DFCA /* CustomURLSessionMock.swift */; };
8583971F8E9E51E9B7A4FCC6 /* PurchasingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8384E2DB0A3627BE1CCB7D /* PurchasingCoordinator.swift */; };
87B66787F6EB43DA80667C36 /* PageViewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E321E7EEC07CA9A8B9A5619 /* PageViewData.swift */; };
880BBB2099D3112F256E6AE2 /* IntroOfferEligibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93FACE677755EAA3EA4E67A8 /* IntroOfferEligibility.swift */; };
88A5CA6515126BD3D09E0563 /* LimitedQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B921746BEC8F63DDB65C634 /* LimitedQueue.swift */; };
88D22C84ACDED44E3952C786 /* SK2ObserverModePurchaseDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC8705042D6AA74D40350A9 /* SK2ObserverModePurchaseDetector.swift */; };
Expand Down Expand Up @@ -870,6 +873,7 @@
8D5F8BE7E93645C0FCA49E4A /* PopupTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupTransition.swift; sourceTree = "<group>"; };
8D9545633A97A2E63FEDF78A /* SWWebViewLoadingHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SWWebViewLoadingHandler.swift; sourceTree = "<group>"; };
8DE36D141F461F6E945823FA /* Future+Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Future+Async.swift"; sourceTree = "<group>"; };
8E321E7EEC07CA9A8B9A5619 /* PageViewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageViewData.swift; sourceTree = "<group>"; };
8E3589BB187C8C6AA5C9DE71 /* FakeContactsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeContactsStore.swift; sourceTree = "<group>"; };
8E441343EAC43B2ECF35F929 /* SuperwallDelegateAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuperwallDelegateAdapter.swift; sourceTree = "<group>"; };
8E9E1A8F57B5DCA4CD16296F /* Dictionary+Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Keys.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -922,6 +926,7 @@
A22E703895B07CF172665846 /* PaywallLoadingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallLoadingState.swift; sourceTree = "<group>"; };
A2D40088A465E104CF5C67CC /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = "<group>"; };
A3781CF21200CD2333F6779A /* GetPaywallManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetPaywallManager.swift; sourceTree = "<group>"; };
A3F306D67A9F3A43D082DD83 /* PresentationIdTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationIdTests.swift; sourceTree = "<group>"; };
A3F4F74393061C17CEB18F90 /* ManagedEventData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedEventData.swift; sourceTree = "<group>"; };
A40D9BA2449503F4B7F5B7A6 /* Array+Guarded.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Guarded.swift"; sourceTree = "<group>"; };
A4493EE88B00CADF85EF1196 /* PublicIdentity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicIdentity.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1029,6 +1034,7 @@
C937320625239F3E10FE8D8E /* PermissionsHandler+Location.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PermissionsHandler+Location.swift"; sourceTree = "<group>"; };
C9B0C261DCC1ED74DD2BF3EA /* HiddenListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiddenListener.swift; sourceTree = "<group>"; };
CA65A320EE640CDB878F43E9 /* UIWindow+Landscape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIWindow+Landscape.swift"; sourceTree = "<group>"; };
CB7C70BFD23FD038393FD6DC /* PageViewMessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageViewMessageTests.swift; sourceTree = "<group>"; };
CB8384E2DB0A3627BE1CCB7D /* PurchasingCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchasingCoordinator.swift; sourceTree = "<group>"; };
CB96F8411D5C857311D7811C /* TransactionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionType.swift; sourceTree = "<group>"; };
CB9C9132109020FA03D1D5C7 /* MockExternalPurchaseControllerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockExternalPurchaseControllerFactory.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2061,6 +2067,7 @@
75743C9AAFCAB9D91984F19C /* Presentation */ = {
isa = PBXGroup;
children = (
A3F306D67A9F3A43D082DD83 /* PresentationIdTests.swift */,
43F99E26CAFD72F228189A4D /* Audience Logic */,
B2C3E282003472D3326477C4 /* Internal Presentation */,
);
Expand Down Expand Up @@ -2965,6 +2972,7 @@
F4AE7105F72063122615EFF1 /* Message Handling */ = {
isa = PBXGroup;
children = (
8E321E7EEC07CA9A8B9A5619 /* PageViewData.swift */,
CC653A44D9B40812BDDD94E7 /* PaywallMessage.swift */,
BF61DCA9CF170E0AFC507BAE /* PaywallMessageHandler.swift */,
260AE52B33B132D5A5C04911 /* PaywallWebEvent.swift */,
Expand Down Expand Up @@ -2997,6 +3005,7 @@
FD8F67EFF69ECDBE85EB24F5 /* Message Handling */ = {
isa = PBXGroup;
children = (
CB7C70BFD23FD038393FD6DC /* PageViewMessageTests.swift */,
F798D9662212AD1CC75666F3 /* PaywallMessageHandlerDelegateMock.swift */,
B45A6006E4299E75E91CC2ED /* PaywallMessageHandlerTests.swift */,
EC91544C3B7D209A8D51397F /* RawWebMessageHandlerTests.swift */,
Expand Down Expand Up @@ -3209,6 +3218,7 @@
58185F7A0770111BDE259936 /* NetworkTests.swift in Sources */,
F0013E500B7F2113857F8161 /* NotificationSchedulerTests.swift in Sources */,
A191F045B8A9EE2D4A3B757D /* OccurrenceLogicTests.swift in Sources */,
80A96673A17176DD5EFE1FA5 /* PageViewMessageTests.swift in Sources */,
27E396F717A62BA4E0D98086 /* PaywallCacheLogicTests.swift in Sources */,
2205A0CC8F059B3D6231C603 /* PaywallLogicTests.swift in Sources */,
23CD6038DD65F057C81A412D /* PaywallManagerLogicTests.swift in Sources */,
Expand All @@ -3225,6 +3235,7 @@
4A4E5413A8753AFB624D325D /* PermissionTypeTests.swift in Sources */,
A3A0961A4A230C10B8896400 /* PopupTransitionTests.swift in Sources */,
3BE562844FD54486450CE6BB /* PresentPaywallOperatorTests.swift in Sources */,
3652D5EE4C172D623BDEE7E4 /* PresentationIdTests.swift in Sources */,
68FF8D03BAD0F2BE33B9C976 /* ProductPurchaserSK1Tests.swift in Sources */,
A44BAE75AAE4713FAE38F992 /* ProductsFetcherSK1.swift in Sources */,
847E0BD4BDA515E47608F6A1 /* ProductsFetcherSK2Tests.swift in Sources */,
Expand Down Expand Up @@ -3452,6 +3463,7 @@
F75F5E1D503B9391ADD812EC /* PKCS7.swift in Sources */,
56408549E721E2ED524DEA35 /* PaddingListener.swift in Sources */,
2231B31B4B9A25778069B20A /* PaddleProduct.swift in Sources */,
87B66787F6EB43DA80667C36 /* PageViewData.swift in Sources */,
2D4E15921C454AC9B9C13709 /* PassableValue.swift in Sources */,
F605AA51AB24B564D3A21B07 /* Paywall.swift in Sources */,
A9F9A35AEC72D17C7C15DAD4 /* PaywallArchiveManager.swift in Sources */,
Expand Down
Loading
Loading