Skip to content

Commit 0529c5a

Browse files
committed
screen id is added to checkout initiated and post subscriptions
1 parent 368c1ec commit 0529c5a

File tree

11 files changed

+54
-42
lines changed

11 files changed

+54
-42
lines changed

ApphudSDK.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'ApphudSDK'
3-
s.version = '4.0.0-beta5'
3+
s.version = '4.0.0'
44
s.summary = 'Build and Measure In-App Subscriptions on iOS.'
55
s.description = 'Apphud covers every aspect when it comes to In-App Subscriptions from integration to analytics on iOS and Android.'
66
s.homepage = 'https://github.com/apphud/ApphudSDK'

Examples/ApphudDemoSwift/ApphudSDKDemo/AppDelegate.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, @preconcurrency UNUserNot
2424

2525
Apphud.start(apiKey: "YOUR_API_KEY")
2626
Apphud.setDeviceIdentifiers(idfa: nil, idfv: UIDevice.current.identifierForVendor?.uuidString)
27-
fetchIDFA()
27+
// fetchIDFA()
2828

2929
Apphud.preloadPaywallScreens(placementIdentifiers: ["MY_PLAYWALL_PLACEMENT_ID", "ANOTHER_PLACEMENT_ID"])
3030

@@ -35,7 +35,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, @preconcurrency UNUserNot
3535
Apphud.incrementUserProperty(key: .init("coins_count"), by: 2)
3636
// Apphud.setDelegate(self)
3737
Apphud.setUIDelegate(self)
38-
registerForNotifications()
38+
// registerForNotifications()
3939

4040
return true
4141
}

Sources/ApphudUI/ApphudPaywallScreenController+I.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ extension ApphudPaywallScreenController: WKUIDelegate {
164164
if self.useSystemLoadingIndicator {
165165
showLoadingIndicator()
166166
}
167-
168-
Apphud.purchase(product) { [weak self] result in
167+
168+
ApphudInternal.shared.purchase(productId: product.productId, product: product, validate: true, purchasingFromScreen: true) { [weak self] result in
169169
if let self {
170170
self.hideLoadingIndicator()
171171
self.onTransactionCompleted?(result)

Sources/ApphudUI/ApphudScreenController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ class ApphudScreenController: UIViewController {
273273

274274
ApphudInternal.shared.uiDelegate?.apphudWillPurchase?(product: product, offerID: offerID!, screenName: self.rule.screen_name)
275275

276-
ApphudInternal.shared.purchasePromo(skProduct: product, apphudProduct: nil, discountID: offerID!) { (result) in
276+
ApphudInternal.shared.purchasePromo(skProduct: product, apphudProduct: nil, discountID: offerID!, fromScreen: true) { (result) in
277277
self.handlePurchaseResult(product: product, offerID: offerID!, result: result)
278278
}
279279
} else {
@@ -287,7 +287,7 @@ class ApphudScreenController: UIViewController {
287287

288288
ApphudInternal.shared.uiDelegate?.apphudWillPurchase?(product: product, offerID: nil, screenName: self.rule.screen_name)
289289

290-
ApphudInternal.shared.purchase(productId: product.productIdentifier, product: nil, validate: true) { result in
290+
ApphudInternal.shared.purchase(productId: product.productIdentifier, product: nil, validate: true, purchasingFromScreen: true) { result in
291291
self.handlePurchaseResult(product: product, result: result)
292292
}
293293
}

Sources/Internal/ApphudAsyncStoreKit.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ internal class ApphudAsyncStoreKit {
9090

9191
do {
9292

93-
ApphudLoggerService.shared.paywallCheckoutInitiated(apphudProduct: apphudProduct, productId: product.id)
93+
ApphudLoggerService.shared.paywallCheckoutInitiated(apphudProduct: apphudProduct, productId: product.id, screenId: nil)
9494
#if os(iOS) || os(tvOS) || os(macOS) || os(watchOS)
9595
let result = try await product.purchase(options: options)
9696
#else

Sources/Internal/ApphudInternal+Eligibility.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extension ApphudInternal {
3131
} else if self.currentUser?.subscriptions.count ?? 0 == 0 && !UserDefaults.standard.bool(forKey: didSendReceiptForPromoEligibility) {
3232
if let receiptString = apphudReceiptDataString() {
3333
apphudLog("Restoring subscriptions for promo eligibility check")
34-
self.submitReceipt(product: nil, apphudProduct: nil, transaction: nil, receiptString: receiptString, notifyDelegate: true, eligibilityCheck: true, callback: { _ in
34+
self.submitReceipt(product: nil, apphudProduct: nil, transaction: nil, receiptString: receiptString, notifyDelegate: true, eligibilityCheck: true, fromScreen: false, callback: { _ in
3535
UserDefaults.standard.set(true, forKey: didSendReceiptForPromoEligibility)
3636
Task {
3737
let response = await self._checkPromoEligibilitiesForRegisteredUser(products: products)
@@ -106,7 +106,7 @@ extension ApphudInternal {
106106
} else if self.currentUser?.subscriptions.count ?? 0 == 0 && !UserDefaults.standard.bool(forKey: didSendReceiptForIntroEligibility) {
107107
if let receiptString = apphudReceiptDataString() {
108108
apphudLog("Restoring subscriptions for intro eligibility check")
109-
self.submitReceipt(product: nil, apphudProduct: nil, transaction: nil, receiptString: receiptString, notifyDelegate: true, eligibilityCheck: true, callback: { _ in
109+
self.submitReceipt(product: nil, apphudProduct: nil, transaction: nil, receiptString: receiptString, notifyDelegate: true, eligibilityCheck: true, fromScreen: false, callback: { _ in
110110
UserDefaults.standard.set(true, forKey: didSendReceiptForIntroEligibility)
111111
Task {
112112
let response = await self._checkIntroEligibilitiesForRegisteredUser(products: products)

Sources/Internal/ApphudInternal+Purchase.swift

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ extension ApphudInternal {
116116
transactionProductIdentifier: productID,
117117
transactionState: isRecentlyPurchased ? .purchased : nil,
118118
receiptString: receipt,
119-
notifyDelegate: true) { _ in
119+
notifyDelegate: true,
120+
fromScreen: false) { _ in
120121
continuation.resume(returning: true)
121122
}
122123
}
@@ -166,7 +167,7 @@ extension ApphudInternal {
166167
apphudLog("App Store receipt is missing, but got transaction. Will try to submit transaction instead..", forceDisplay: true)
167168
}
168169

169-
self.submitReceipt(product: nil, apphudProduct: nil, transaction: transaction, receiptString: receiptString, notifyDelegate: true, eligibilityCheck: true, callback: { error in
170+
self.submitReceipt(product: nil, apphudProduct: nil, transaction: transaction, receiptString: receiptString, notifyDelegate: true, eligibilityCheck: true, fromScreen: false, callback: { error in
170171
let result = self.purchaseResult(productId: transaction.payment.productIdentifier, transaction: transaction, error: error)
171172
callback(result)
172173
})
@@ -199,18 +200,18 @@ extension ApphudInternal {
199200

200201
performWhenUserRegistered {
201202

202-
self.submitReceipt(product: nil, apphudProduct: nil, transaction: transaction, receiptString: receiptString, notifyDelegate: true) { error in
203+
self.submitReceipt(product: nil, apphudProduct: nil, transaction: transaction, receiptString: receiptString, notifyDelegate: true, fromScreen: false) { error in
203204
self.restorePurchasesCallback?(self.currentUser?.subscriptions, self.currentUser?.purchases, error)
204205
self.restorePurchasesCallback = nil
205206
}
206207
}
207208
}
208209

209-
internal func submitReceipt(product: SKProduct, transaction: SKPaymentTransaction?, apphudProduct: ApphudProduct? = nil, callback: ((ApphudPurchaseResult) -> Void)?) {
210+
internal func submitReceipt(product: SKProduct, transaction: SKPaymentTransaction?, apphudProduct: ApphudProduct? = nil, fromScreen: Bool, callback: ((ApphudPurchaseResult) -> Void)?) {
210211

211212
let block: (String?) -> Void = { receiptStr in
212213
if transaction != nil {
213-
self.submitReceipt(product: product, apphudProduct: apphudProduct, transaction: transaction, receiptString: receiptStr, notifyDelegate: true) { error in
214+
self.submitReceipt(product: product, apphudProduct: apphudProduct, transaction: transaction, receiptString: receiptStr, notifyDelegate: true, fromScreen: fromScreen) { error in
214215
Task { @MainActor in
215216
let result = self.purchaseResult(productId: product.productIdentifier, transaction: transaction, error: error)
216217
callback?(result)
@@ -242,7 +243,7 @@ extension ApphudInternal {
242243
}
243244
}
244245

245-
internal func submitReceipt(product: SKProduct?, apphudProduct: ApphudProduct?, transaction: SKPaymentTransaction?, receiptString: String?, notifyDelegate: Bool, eligibilityCheck: Bool = false, callback: ApphudNSErrorCallback?) {
246+
internal func submitReceipt(product: SKProduct?, apphudProduct: ApphudProduct?, transaction: SKPaymentTransaction?, receiptString: String?, notifyDelegate: Bool, eligibilityCheck: Bool = false, fromScreen: Bool, callback: ApphudNSErrorCallback?) {
246247

247248
let productId = product?.productIdentifier ?? transaction?.payment.productIdentifier
248249
let finalProduct = product ?? ApphudStoreKitWrapper.shared.products.first(where: { $0.productIdentifier == productId })
@@ -257,6 +258,7 @@ extension ApphudInternal {
257258
receiptString: receiptString,
258259
notifyDelegate: notifyDelegate,
259260
eligibilityCheck: eligibilityCheck,
261+
fromScreen: fromScreen,
260262
callback: callback)
261263
}
262264
}
@@ -278,6 +280,7 @@ extension ApphudInternal {
278280
receiptString: String?,
279281
notifyDelegate: Bool,
280282
eligibilityCheck: Bool = false,
283+
fromScreen: Bool,
281284
callback: ApphudNSErrorCallback?) async {
282285

283286
await MainActor.run {
@@ -322,6 +325,11 @@ extension ApphudInternal {
322325
}
323326

324327
if hasMadePurchase, let purchasedApphudProduct = apphudProduct ?? purchasingProduct, purchasedApphudProduct.productId == transactionProductIdentifier {
328+
329+
if fromScreen {
330+
params["screen_id"] = purchasedApphudProduct.paywall?.screen?.id
331+
}
332+
325333
params["product_bundle_id"] = purchasedApphudProduct.id
326334
params["paywall_id"] = purchasedApphudProduct.paywallId
327335
params["placement_id"] = purchasedApphudProduct.placementId
@@ -445,27 +453,27 @@ extension ApphudInternal {
445453

446454
@MainActor
447455
@available(iOS 13.0.0, macOS 11.0, watchOS 6.0, tvOS 13.0, *)
448-
internal func purchase(productId: String, product: ApphudProduct?, validate: Bool, isPurchasing: Binding<Bool>? = nil, value: Double? = nil) async -> ApphudPurchaseResult {
456+
internal func purchase(productId: String, product: ApphudProduct?, validate: Bool, isPurchasing: Binding<Bool>? = nil, fromScreen: Bool, value: Double? = nil) async -> ApphudPurchaseResult {
449457
await withUnsafeContinuation { continuation in
450458
isPurchasing?.wrappedValue = true
451-
purchase(productId: productId, product: product, validate: validate, callback: { result in
459+
purchase(productId: productId, product: product, validate: validate, purchasingFromScreen: fromScreen, callback: { result in
452460
isPurchasing?.wrappedValue = false
453461
continuation.resume(returning: result)
454462
})
455463
}
456464
}
457465

458-
@MainActor internal func purchase(productId: String, product: ApphudProduct?, validate: Bool, value: Double? = nil, callback: ((ApphudPurchaseResult) -> Void)?) {
459-
466+
@MainActor internal func purchase(productId: String, product: ApphudProduct?, validate: Bool, purchasingFromScreen: Bool, value: Double? = nil, callback: ((ApphudPurchaseResult) -> Void)?) {
467+
460468
let skProduct = product?.skProduct ?? ApphudStoreKitWrapper.shared.products.first(where: { $0.productIdentifier == productId })
461469

462470
if let skProduct = skProduct {
463-
purchase(product: skProduct, apphudProduct: product, validate: validate, value: value, callback: callback)
471+
purchase(product: skProduct, apphudProduct: product, validate: validate, fromScreen: purchasingFromScreen, value: value, callback: callback)
464472
} else {
465473
apphudLog("Product with id \(productId) not found, re-fetching from App Store...")
466474
ApphudStoreKitWrapper.shared.fetchProducts(productIds: [productId]) { prds in
467475
if let sk = prds?.first(where: { $0.productIdentifier == productId }) {
468-
self.purchase(product: sk, apphudProduct: product, validate: validate, value: value, callback: callback)
476+
self.purchase(product: sk, apphudProduct: product, validate: validate, fromScreen: purchasingFromScreen, value: value, callback: callback)
469477
} else {
470478
let message = "Unable to start payment because product identifier is invalid: [\([productId])]"
471479
apphudLog(message, forceDisplay: true)
@@ -476,12 +484,12 @@ extension ApphudInternal {
476484
}
477485
}
478486

479-
internal func purchasePromo(skProduct: SKProduct?, apphudProduct: ApphudProduct?, discountID: String, callback: ((ApphudPurchaseResult) -> Void)?) {
487+
internal func purchasePromo(skProduct: SKProduct?, apphudProduct: ApphudProduct?, discountID: String, fromScreen: Bool, callback: ((ApphudPurchaseResult) -> Void)?) {
480488

481489
let skCallback: ((SKProduct) -> Void) = { skProduct in
482490
self.signPromoOffer(productID: skProduct.productIdentifier, discountID: discountID) { (paymentDiscount, _) in
483491
if let paymentDiscount = paymentDiscount {
484-
self.purchasePromo(skProduct: skProduct, product: apphudProduct, discount: paymentDiscount, callback: callback)
492+
self.purchasePromo(skProduct: skProduct, product: apphudProduct, discount: paymentDiscount, fromScreen: fromScreen, callback: callback)
485493
} else {
486494
callback?(ApphudPurchaseResult(nil, nil, nil, ApphudError(message: "Could not sign offer id: \(discountID), product id: \(skProduct.productIdentifier)")))
487495
}
@@ -504,8 +512,11 @@ extension ApphudInternal {
504512

505513
// MARK: - Private purchase methods
506514

507-
private func purchase(product: SKProduct, apphudProduct: ApphudProduct?, validate: Bool, value: Double? = nil, callback: ((ApphudPurchaseResult) -> Void)?) {
508-
ApphudLoggerService.shared.paywallCheckoutInitiated(apphudProduct: apphudProduct, productId: product.productIdentifier)
515+
private func purchase(product: SKProduct, apphudProduct: ApphudProduct?, validate: Bool, fromScreen: Bool, value: Double? = nil, callback: ((ApphudPurchaseResult) -> Void)?) {
516+
517+
let screenId = fromScreen ? apphudProduct?.paywall?.screen?.id : nil
518+
519+
ApphudLoggerService.shared.paywallCheckoutInitiated(apphudProduct: apphudProduct, productId: product.productIdentifier, screenId: screenId)
509520

510521
purchasingProduct = apphudProduct
511522

@@ -517,16 +528,16 @@ extension ApphudInternal {
517528

518529
Task { @MainActor in
519530
if validate {
520-
self.handleTransaction(product: product, transaction: transaction, error: error, apphudProduct: apphudProduct, callback: callback)
531+
self.handleTransaction(product: product, transaction: transaction, error: error, apphudProduct: apphudProduct, fromScreen: fromScreen, callback: callback)
521532
} else {
522-
self.handleTransaction(product: product, transaction: transaction, error: error, apphudProduct: apphudProduct, callback: nil)
533+
self.handleTransaction(product: product, transaction: transaction, error: error, apphudProduct: apphudProduct, fromScreen: fromScreen, callback: nil)
523534
callback?(ApphudPurchaseResult(nil, nil, transaction, error))
524535
}
525536
}
526537
}
527538
}
528539

529-
private func purchasePromo(skProduct: SKProduct, product: ApphudProduct?, discount: SKPaymentDiscount, callback: ((ApphudPurchaseResult) -> Void)?) {
540+
private func purchasePromo(skProduct: SKProduct, product: ApphudProduct?, discount: SKPaymentDiscount, fromScreen: Bool, callback: ((ApphudPurchaseResult) -> Void)?) {
530541

531542
purchasingProduct = product
532543

@@ -536,7 +547,7 @@ extension ApphudInternal {
536547
}
537548

538549
Task { @MainActor in
539-
self.handleTransaction(product: skProduct, transaction: transaction, error: error, apphudProduct: product, callback: callback)
550+
self.handleTransaction(product: skProduct, transaction: transaction, error: error, apphudProduct: product, fromScreen: fromScreen, callback: callback)
540551
}
541552
}
542553
}
@@ -545,9 +556,9 @@ extension ApphudInternal {
545556
observerModePurchaseIdentifiers = (paywallId, placementId)
546557
}
547558

548-
@MainActor private func handleTransaction(product: SKProduct, transaction: SKPaymentTransaction, error: Error?, apphudProduct: ApphudProduct?, callback: ((ApphudPurchaseResult) -> Void)?) {
559+
@MainActor private func handleTransaction(product: SKProduct, transaction: SKPaymentTransaction, error: Error?, apphudProduct: ApphudProduct?, fromScreen: Bool, callback: ((ApphudPurchaseResult) -> Void)?) {
549560
if transaction.transactionState == .purchased || transaction.failedWithUnknownReason {
550-
self.submitReceipt(product: product, transaction: transaction, apphudProduct: apphudProduct) { (result) in
561+
self.submitReceipt(product: product, transaction: transaction, apphudProduct: apphudProduct, fromScreen: fromScreen) { (result) in
551562
ApphudStoreKitWrapper.shared.finishTransaction(transaction)
552563
callback?(result)
553564
}

Sources/Internal/ApphudInternal.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ final class ApphudInternal: NSObject {
184184
internal var didHandleBecomeActive = false
185185
internal var respondedStoreKitProducts = false
186186

187+
internal var purchasingFromScreen: Bool = false
187188
internal var purchasingProduct: ApphudProduct?
188189
internal var pendingTransactionID: String?
189190
internal var fallbackMode = false

Sources/Internal/ApphudLoggerService.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class ApphudLoggerService {
4444
ApphudInternal.shared.trackPaywallEvent(params: ["name": "paywall_closed", "properties": ["paywall_id": paywallId, "placement_id": placementId].compactMapValues { $0 }])
4545
}
4646

47-
internal func paywallCheckoutInitiated(apphudProduct: ApphudProduct?, productId: String?) {
48-
ApphudInternal.shared.trackPaywallEvent(params: ["name": "paywall_checkout_initiated", "properties": ["paywall_id": apphudProduct?.paywallId, "placement_id": apphudProduct?.placementId, "product_id": productId, "variation_identifier": apphudProduct?.variationIdentifier, "experiment_id": apphudProduct?.experimentId].compactMapValues { $0 } ])
47+
internal func paywallCheckoutInitiated(apphudProduct: ApphudProduct?, productId: String?, screenId: String?) {
48+
ApphudInternal.shared.trackPaywallEvent(params: ["name": "paywall_checkout_initiated", "properties": ["paywall_id": apphudProduct?.paywallId, "placement_id": apphudProduct?.placementId, "product_id": productId, "variation_identifier": apphudProduct?.variationIdentifier, "screen_id": screenId , "experiment_id": apphudProduct?.experimentId].compactMapValues { $0 } ])
4949
}
5050

5151
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)

Sources/Internal/ApphudStoreKitWrapper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ internal class ApphudStoreKitWrapper: NSObject, SKPaymentTransactionObserver, SK
312312

313313
DispatchQueue.main.async {
314314
if let callback = ApphudInternal.shared.delegate?.apphudShouldStartAppStoreDirectPurchase(product) {
315-
ApphudInternal.shared.purchase(productId: product.productIdentifier, product: nil, validate: true, callback: callback)
315+
ApphudInternal.shared.purchase(productId: product.productIdentifier, product: nil, validate: true, purchasingFromScreen: false, callback: callback)
316316
}
317317
}
318318

0 commit comments

Comments
 (0)