-
Notifications
You must be signed in to change notification settings - Fork 22
/
SuperwallEvent.swift
257 lines (215 loc) · 9.09 KB
/
SuperwallEvent.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//
// File.swift
//
//
// Created by Yusuf Tör on 21/04/2022.
//
import Foundation
/// Analytical events that are automatically tracked by Superwall.
///
/// These events are tracked internally by the SDK and sent to the delegate method ``SuperwallDelegate/handleSuperwallEvent(withInfo:)-pm3v``.
public enum SuperwallEvent {
/// When the user is first seen in the app, regardless of whether the user is logged in or not.
case firstSeen
/// Anytime the app enters the foreground
case appOpen
/// When the app is launched from a cold start
///
/// The raw value of this event can be added to a campaign to trigger a paywall.
case appLaunch
/// When the SDK is configured for the first time.
///
/// The raw value of this event can be added to a campaign to trigger a paywall.
case appInstall
/// When the app is opened at least an hour since last ``appClose``.
///
/// The raw value of this event can be added to a campaign to trigger a paywall.
case sessionStart
/// When the user's subscription status changes.
case subscriptionStatusDidChange
/// Anytime the app leaves the foreground.
case appClose
/// When a user opens the app via a deep link.
///
/// The raw value of this event can be added to a campaign to trigger a paywall.
case deepLink(url: URL)
/// When the tracked event matches an event added as a paywall trigger in a campaign.
///
/// The result of firing the trigger is accessible in the `result` associated value.
case triggerFire(eventName: String, result: TriggerResult)
/// When a paywall is opened.
case paywallOpen(paywallInfo: PaywallInfo)
/// When a paywall is closed.
case paywallClose(paywallInfo: PaywallInfo)
/// When a user manually dismisses a paywall.
case paywallDecline(paywallInfo: PaywallInfo)
/// When the payment sheet is displayed to the user.
case transactionStart(product: StoreProduct, paywallInfo: PaywallInfo)
/// When the payment sheet fails to complete a transaction (ignores user canceling the transaction).
case transactionFail(error: TransactionError, paywallInfo: PaywallInfo)
/// When the user cancels a transaction.
case transactionAbandon(product: StoreProduct, paywallInfo: PaywallInfo)
/// When the user completes checkout in the payment sheet and any product was purchased.
///
/// - Note: The `transaction` is an optional ``StoreTransaction`` object. Most of the time
/// this won't be `nil`. However, it could be `nil` if you are using a ``PurchaseController``
/// and the transaction object couldn't be detected after you return `.purchased` in ``PurchaseController/purchase(product:)``.
case transactionComplete(transaction: StoreTransaction?, product: StoreProduct, paywallInfo: PaywallInfo)
/// When the user successfully completes a transaction for a subscription product with no introductory offers.
case subscriptionStart(product: StoreProduct, paywallInfo: PaywallInfo)
/// When the user successfully completes a transaction for a subscription product with an introductory offer.
case freeTrialStart(product: StoreProduct, paywallInfo: PaywallInfo)
/// When the user successfully restores their purchases.
case transactionRestore(paywallInfo: PaywallInfo)
/// When the transaction took > 5 seconds to show the payment sheet.
case transactionTimeout(paywallInfo: PaywallInfo)
/// When the user attributes are set.
case userAttributes(_ attributes: [String: Any])
/// When the user purchased a non recurring product.
case nonRecurringProductPurchase(product: TransactionProduct, paywallInfo: PaywallInfo)
/// When a paywall's request to Superwall's servers has started.
case paywallResponseLoadStart(triggeredEventName: String?)
/// When a paywall's request to Superwall's servers returned a 404 error.
case paywallResponseLoadNotFound(triggeredEventName: String?)
/// When a paywall's request to Superwall's servers produced an error.
case paywallResponseLoadFail(triggeredEventName: String?)
/// When a paywall's request to Superwall's servers is complete.
case paywallResponseLoadComplete(triggeredEventName: String?, paywallInfo: PaywallInfo)
/// When a paywall's website begins to load.
case paywallWebviewLoadStart(paywallInfo: PaywallInfo)
/// When a paywall's website fails to load.
case paywallWebviewLoadFail(paywallInfo: PaywallInfo)
/// When a paywall's website completes loading.
case paywallWebviewLoadComplete(paywallInfo: PaywallInfo)
/// When the loading of a paywall's website times out.
case paywallWebviewLoadTimeout(paywallInfo: PaywallInfo)
/// When the request to load the paywall's products started.
case paywallProductsLoadStart(triggeredEventName: String?, paywallInfo: PaywallInfo)
/// When the request to load the paywall's products failed.
case paywallProductsLoadFail(triggeredEventName: String?, paywallInfo: PaywallInfo)
/// When the request to load the paywall's products completed.
case paywallProductsLoadComplete(triggeredEventName: String?)
/// When the response to a paywall survey is recorded.
case surveyResponse(
survey: Survey,
selectedOption: SurveyOption,
customResponse: String?,
paywallInfo: PaywallInfo
)
/// Information about the paywall presentation request
case paywallPresentationRequest(
status: PaywallPresentationRequestStatus,
reason: PaywallPresentationRequestStatusReason?
)
var canImplicitlyTriggerPaywall: Bool {
switch self {
case .appInstall,
.sessionStart,
.appLaunch,
.deepLink,
.transactionFail,
.paywallDecline,
.transactionAbandon,
.surveyResponse:
return true
default:
return false
}
}
}
// MARK: - CustomStringConvertible
extension SuperwallEvent: CustomStringConvertible {
/// The string value of the event name.
public var description: String {
return backingData.description
}
}
// MARK: - Backing data
extension SuperwallEvent {
struct BackingData {
let objcEvent: SuperwallEventObjc
let description: String
init(objcEvent: SuperwallEventObjc) {
self.objcEvent = objcEvent
self.description = objcEvent.description
}
}
var backingData: BackingData {
switch self {
case .firstSeen:
return .init(objcEvent: .firstSeen)
case .appOpen:
return .init(objcEvent: .appOpen)
case .appLaunch:
return .init(objcEvent: .appLaunch)
case .appInstall:
return .init(objcEvent: .appInstall)
case .sessionStart:
return .init(objcEvent: .sessionStart)
case .subscriptionStatusDidChange:
return .init(objcEvent: .subscriptionStatusDidChange)
case .appClose:
return .init(objcEvent: .appClose)
case .deepLink:
return .init(objcEvent: .deepLink)
case .triggerFire:
return .init(objcEvent: .triggerFire)
case .paywallOpen:
return .init(objcEvent: .paywallOpen)
case .paywallClose:
return .init(objcEvent: .paywallClose)
case .paywallDecline:
return .init(objcEvent: .paywallDecline)
case .transactionStart:
return .init(objcEvent: .transactionStart)
case .transactionFail:
return .init(objcEvent: .transactionFail)
case .transactionAbandon:
return .init(objcEvent: .transactionAbandon)
case .transactionTimeout:
return .init(objcEvent: .transactionTimeout)
case .transactionComplete:
return .init(objcEvent: .transactionComplete)
case .subscriptionStart:
return .init(objcEvent: .subscriptionStart)
case .freeTrialStart:
return .init(objcEvent: .freeTrialStart)
case .transactionRestore:
return .init(objcEvent: .transactionRestore)
case .userAttributes:
return .init(objcEvent: .userAttributes)
case .nonRecurringProductPurchase:
return .init(objcEvent: .nonRecurringProductPurchase)
case .paywallResponseLoadStart:
return .init(objcEvent: .paywallResponseLoadStart)
case .paywallResponseLoadNotFound:
return .init(objcEvent: .paywallResponseLoadNotFound)
case .paywallResponseLoadFail:
return .init(objcEvent: .paywallResponseLoadFail)
case .paywallResponseLoadComplete:
return .init(objcEvent: .paywallResponseLoadComplete)
case .paywallWebviewLoadStart:
return .init(objcEvent: .paywallWebviewLoadStart)
case .paywallWebviewLoadFail:
return .init(objcEvent: .paywallWebviewLoadFail)
case .paywallWebviewLoadComplete:
return .init(objcEvent: .paywallWebviewLoadComplete)
case .paywallWebviewLoadTimeout:
return .init(objcEvent: .paywallWebviewLoadTimeout)
case .paywallProductsLoadStart:
return .init(objcEvent: .paywallProductsLoadStart)
case .paywallProductsLoadFail:
return .init(objcEvent: .paywallProductsLoadFail)
case .paywallProductsLoadComplete:
return .init(objcEvent: .paywallProductsLoadComplete)
case .paywallPresentationRequest:
return .init(objcEvent: .paywallPresentationRequest)
case .surveyResponse:
return .init(objcEvent: .surveyResponse)
}
}
}
// Using this to silence warnings.
// This is unchecked because of the use of `Any` in `[String: Any]` user attributes.
// Also, PaywallInfo is not Sendable.
extension SuperwallEvent: @unchecked Sendable {}