@@ -19,34 +19,57 @@ extension TelemetryDeck {
19
19
parameters: [ String : String ] = [ : ] ,
20
20
customUserID: String ? = nil
21
21
) {
22
- let priceValueInNativeCurrency = NSDecimalNumber ( decimal: transaction. price ?? Decimal ( ) ) . doubleValue
23
-
24
- let priceValueInUSD : Double
25
-
26
- if #available( iOS 16 , macOS 13 , tvOS 16 , watchOS 9 , * ) {
27
- if transaction. currency? . identifier == " USD " {
28
- priceValueInUSD = priceValueInNativeCurrency
29
- } else if
30
- let currencyCode = transaction. currency? . identifier,
31
- let oneUSDExchangeRate = self . currencyCodeToOneUSDExchangeRate [ currencyCode]
22
+ if #available( iOS 17 . 2 , macOS 14 . 2 , tvOS 17 . 2 , visionOS 1 . 1 , watchOS 10 . 2 , * ) {
23
+ // detect if the purchase is a free trial (using modern APIs)
24
+ if
25
+ transaction. productType == . autoRenewable,
26
+ transaction. offer? . type == . introductory,
27
+ transaction. price == nil || transaction. price!. isZero
32
28
{
33
- priceValueInUSD = priceValueInNativeCurrency / oneUSDExchangeRate
29
+ self . reportFreeTrial ( transaction : transaction , parameters : parameters , customUserID : customUserID )
34
30
} else {
35
- priceValueInUSD = 0
31
+ self . reportPaidPurchase ( transaction : transaction , parameters : parameters , customUserID : customUserID )
36
32
}
37
33
} else {
38
- if transaction . currencyCode == " USD " {
39
- priceValueInUSD = priceValueInNativeCurrency
40
- } else if
41
- let currencyCode = transaction . currencyCode ,
42
- let oneUSDExchangeRate = self . currencyCodeToOneUSDExchangeRate [ currencyCode ]
34
+ // detect if the purchase is a free trial (using legacy APIs on older systems)
35
+ if
36
+ transaction . productType == . autoRenewable ,
37
+ transaction . offerType == . introductory ,
38
+ transaction . price == nil || transaction . price! . isZero
43
39
{
44
- priceValueInUSD = priceValueInNativeCurrency / oneUSDExchangeRate
40
+ self . reportFreeTrial ( transaction : transaction , parameters : parameters , customUserID : customUserID )
45
41
} else {
46
- priceValueInUSD = 0
42
+ self . reportPaidPurchase ( transaction : transaction , parameters : parameters , customUserID : customUserID )
47
43
}
48
44
}
45
+ }
46
+
47
+ private static func reportFreeTrial(
48
+ transaction: StoreKit . Transaction ,
49
+ parameters: [ String : String ] ,
50
+ customUserID: String ?
51
+ ) {
52
+ self . internalSignal (
53
+ " TelemetryDeck.Purchase.freeTrialStarted " ,
54
+ parameters: self . purchaseParameters ( transaction: transaction) . merging ( parameters) { $1 } ,
55
+ customUserID: customUserID
56
+ )
57
+ }
58
+
59
+ private static func reportPaidPurchase(
60
+ transaction: StoreKit . Transaction ,
61
+ parameters: [ String : String ] ,
62
+ customUserID: String ?
63
+ ) {
64
+ self . internalSignal (
65
+ " TelemetryDeck.Purchase.completed " ,
66
+ parameters: self . purchaseParameters ( transaction: transaction) . merging ( parameters) { $1 } ,
67
+ floatValue: self . calculatePriceInUSD ( transaction: transaction) ,
68
+ customUserID: customUserID
69
+ )
70
+ }
49
71
72
+ private static func purchaseParameters( transaction: StoreKit . Transaction ) -> [ String : String ] {
50
73
let countryCode : String
51
74
if #available( iOS 17 , macOS 14 , tvOS 17 , watchOS 10 , * ) {
52
75
countryCode = transaction. storefront. countryCode
@@ -73,12 +96,38 @@ extension TelemetryDeck {
73
96
}
74
97
}
75
98
76
- self . internalSignal (
77
- " TelemetryDeck.Purchase.completed " ,
78
- parameters: purchaseParameters. merging ( parameters) { $1 } ,
79
- floatValue: priceValueInUSD,
80
- customUserID: customUserID
81
- )
99
+ return purchaseParameters
100
+ }
101
+
102
+ private static func calculatePriceInUSD( transaction: StoreKit . Transaction ) -> Double {
103
+ let priceValueInNativeCurrency = NSDecimalNumber ( decimal: transaction. price ?? Decimal ( ) ) . doubleValue
104
+ let priceValueInUSD : Double
105
+
106
+ if #available( iOS 16 , macOS 13 , tvOS 16 , watchOS 9 , * ) {
107
+ if transaction. currency? . identifier == " USD " {
108
+ priceValueInUSD = priceValueInNativeCurrency
109
+ } else if
110
+ let currencyCode = transaction. currency? . identifier,
111
+ let oneUSDExchangeRate = self . currencyCodeToOneUSDExchangeRate [ currencyCode]
112
+ {
113
+ priceValueInUSD = priceValueInNativeCurrency / oneUSDExchangeRate
114
+ } else {
115
+ priceValueInUSD = 0
116
+ }
117
+ } else {
118
+ if transaction. currencyCode == " USD " {
119
+ priceValueInUSD = priceValueInNativeCurrency
120
+ } else if
121
+ let currencyCode = transaction. currencyCode,
122
+ let oneUSDExchangeRate = self . currencyCodeToOneUSDExchangeRate [ currencyCode]
123
+ {
124
+ priceValueInUSD = priceValueInNativeCurrency / oneUSDExchangeRate
125
+ } else {
126
+ priceValueInUSD = 0
127
+ }
128
+ }
129
+
130
+ return priceValueInUSD
82
131
}
83
132
84
133
private static let currencyCodeToOneUSDExchangeRate : [ String : Double ] = [
0 commit comments