@@ -50,6 +50,9 @@ public class AppsFlyerDestination: UIResponder, DestinationPlugin {
50
50
private weak var segDelegate : AppsFlyerLibDelegate ?
51
51
private weak var segDLDelegate : DeepLinkDelegate ?
52
52
53
+ private var isFirstLaunch = true
54
+ private var manualMode : Bool = false
55
+
53
56
// MARK: - Initialization
54
57
55
58
/// Creates and returns an AppsFlyer destination plugin for the Segment SDK
@@ -60,9 +63,11 @@ public class AppsFlyerDestination: UIResponder, DestinationPlugin {
60
63
/// - segDelegate: When provided, this delegate will get called back for all AppsFlyerDelegate methods - ``onConversionDataSuccess(_:)``, ``onConversionDataFail(_:)``, ``onAppOpenAttribution(_:)``, ``onAppOpenAttributionFailure(_:)``
61
64
/// - segDLDelegate: When provided, this delegate will get called back for all DeepLinkDelegate routines, or just ``didResolveDeeplink``
62
65
public init ( segDelegate: AppsFlyerLibDelegate ? = nil ,
63
- segDLDelegate: DeepLinkDelegate ? = nil ) {
66
+ segDLDelegate: DeepLinkDelegate ? = nil ,
67
+ manualMode: Bool = false ) {
64
68
self . segDelegate = segDelegate
65
69
self . segDLDelegate = segDLDelegate
70
+ self . manualMode = manualMode
66
71
}
67
72
68
73
// MARK: - Plugin
@@ -75,15 +80,46 @@ public class AppsFlyerDestination: UIResponder, DestinationPlugin {
75
80
76
81
AppsFlyerLib . shared ( ) . appsFlyerDevKey = settings. appsFlyerDevKey
77
82
AppsFlyerLib . shared ( ) . appleAppID = settings. appleAppID
83
+ AppsFlyerLib . shared ( ) . setPluginInfo ( plugin: Plugin . segment, version: " 2.0.0 " , additionalParams: [ " Segment " : " Analytics-Swift " , " Platform " : " iOS " ] )
78
84
79
- AppsFlyerLib . shared ( ) . waitForATTUserAuthorization ( timeoutInterval: 60 ) //OPTIONAL
85
+ // Commented this in order to let the developer set it as suits them.
86
+ // It is available by the developer with AppsFlyerLib.shared() on their iOS native code.
87
+ // AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60) //OPTIONAL
80
88
AppsFlyerLib . shared ( ) . deepLinkDelegate = self //OPTIONAL
89
+ // AppsFlyerLib.shared().isDebug = true
81
90
82
91
let trackAttributionData = settings. trackAttributionData
83
92
84
93
if trackAttributionData ?? false {
85
94
AppsFlyerLib . shared ( ) . delegate = self
86
95
}
96
+
97
+ // Manual mode is a mode which let's the developer the abillity to start the SDK.
98
+ // Once setting manualMode=true in the init, the develper should use startAppsflyerSDK method to start the SDK.
99
+ // Once started the SDK it will be start automatically by the life cycle - didBecomeActiveNotification.
100
+ if ( !manualMode) {
101
+ startAFSDK ( )
102
+ NotificationCenter . default. addObserver ( self , selector: #selector( listenerStartSDK) , name: UIApplication . didBecomeActiveNotification, object: nil )
103
+ }
104
+ }
105
+
106
+ // This is for the Manual Mode !
107
+ // Once calling this function every didBecomeActive start will be called.
108
+ public func startAppsflyerSDK( ) {
109
+ startAFSDK ( )
110
+ NotificationCenter . default. addObserver ( self , selector: #selector( listenerStartSDK) , name: UIApplication . didBecomeActiveNotification, object: nil )
111
+ }
112
+
113
+ private func startAFSDK( ) {
114
+ AppsFlyerLib . shared ( ) . start ( )
115
+ }
116
+
117
+ @objc func listenerStartSDK( ) {
118
+ if ( isFirstLaunch) {
119
+ isFirstLaunch = false
120
+ return
121
+ }
122
+ startAFSDK ( )
87
123
}
88
124
89
125
public func identify( event: IdentifyEvent ) -> IdentifyEvent ? {
@@ -92,59 +128,62 @@ public class AppsFlyerDestination: UIResponder, DestinationPlugin {
92
128
}
93
129
94
130
if let traits = event. traits? . dictionaryValue {
95
- var aFTraits : [ AnyHashable : Any ] = [ : ]
131
+ var afTraits : [ AnyHashable : Any ] = [ : ]
96
132
97
133
if let email = traits [ " email " ] as? String {
98
- aFTraits [ " email " ] = email
134
+ afTraits [ " email " ] = email
99
135
}
100
136
101
137
if let firstName = traits [ " firstName " ] as? String {
102
- aFTraits [ " firstName " ] = firstName
138
+ afTraits [ " firstName " ] = firstName
103
139
}
104
140
105
141
if let lastName = traits [ " lastName " ] as? String {
106
- aFTraits [ " lastName " ] = lastName
142
+ afTraits [ " lastName " ] = lastName
143
+ }
144
+
145
+ if let username = traits [ " username " ] as? String {
146
+ afTraits [ " username " ] = username
107
147
}
108
148
109
149
if traits [ " currencyCode " ] != nil {
110
150
AppsFlyerLib . shared ( ) . currencyCode = traits [ " currencyCode " ] as? String
111
151
}
112
152
113
- AppsFlyerLib . shared ( ) . customData = aFTraits
153
+ AppsFlyerLib . shared ( ) . customData = afTraits
114
154
}
115
155
116
156
return event
117
157
}
118
158
119
159
public func track( event: TrackEvent ) -> TrackEvent ? {
120
-
160
+ // Verify we are not looping an event.
161
+ if ( event. event == " Install Attributed " ||
162
+ event. event == " Organic Install " ||
163
+ event. event == " Deep Link Opened " ||
164
+ event. event == " Direct Deep Link " ||
165
+ event. event == " Deferred Deep Link " ) {
166
+ return nil
167
+ }
121
168
var properties = event. properties? . dictionaryValue
122
169
123
170
let revenue : Double ? = extractRevenue ( key: " revenue " , from: properties)
124
- let currency : String ? = extractCurrency ( key: " currency " , from: properties, withDefault : " USD " )
171
+ let currency : String ? = extractCurrency ( key: " currency " , from: properties)
125
172
126
173
if let afRevenue = revenue, let afCurrency = currency {
127
174
properties ? [ " af_revenue " ] = afRevenue
128
175
properties ? [ " af_currency " ] = afCurrency
129
176
130
177
properties? . removeValue ( forKey: " revenue " )
131
- properties? . removeValue ( forKey: " currency " )
132
-
133
- AppsFlyerLib . shared ( ) . logEvent ( event. event, withValues: properties)
134
-
135
- } else {
136
- AppsFlyerLib . shared ( ) . logEvent ( event. event, withValues: properties)
178
+ properties? . removeValue ( forKey: " currency " )
137
179
}
138
-
180
+
181
+ AppsFlyerLib . shared ( ) . logEvent ( event. event, withValues: properties)
139
182
return event
140
183
}
141
184
}
142
185
143
186
extension AppsFlyerDestination : RemoteNotifications , iOSLifecycle {
144
- public func applicationDidBecomeActive( application: UIApplication ? ) {
145
- AppsFlyerLib . shared ( ) . start ( )
146
- }
147
-
148
187
public func openURL( _ url: URL , options: [ UIApplication . OpenURLOptionsKey : Any ] ) {
149
188
AppsFlyerLib . shared ( ) . handleOpen ( url, options: options)
150
189
}
@@ -168,25 +207,30 @@ extension AppsFlyerDestination: UserActivities {
168
207
// https://github.com/AppsFlyerSDK/segment-appsflyer-ios/blob/master/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m#L148
169
208
extension AppsFlyerDestination {
170
209
internal func extractRevenue( key: String , from properties: [ String : Any ] ? ) -> Double ? {
210
+ guard let value = properties ? [ key] else {
211
+ return nil
212
+ }
171
213
172
- guard let revenueProperty = properties ? [ key] as? Double else { return nil }
173
-
174
- if let revenue = properties ? [ " revenue " ] as? String {
175
- let revenueProperty = Double ( revenue)
176
- return revenueProperty
177
-
214
+ if let doubleValue = value as? Double {
215
+ return doubleValue
216
+ } else if let stringValue = value as? String {
217
+ return Double ( stringValue)
178
218
}
179
- return revenueProperty
219
+
220
+ return nil
180
221
}
181
222
182
223
183
- internal func extractCurrency( key: String , from properties: [ String : Any ] ? , withDefault value: String ? = nil ) -> String ? {
224
+ internal func extractCurrency( key: String , from properties: [ String : Any ] ? ) -> String ? {
225
+ guard let value = properties ? [ key] else {
226
+ return nil
227
+ }
184
228
185
- if let currency = properties ? [ key ] as? String {
186
- return currency
229
+ if let stringValue = value as? String {
230
+ return stringValue
187
231
}
188
232
189
- return " USD "
233
+ return nil
190
234
}
191
235
192
236
}
@@ -233,9 +277,7 @@ extension AppsFlyerDestination: AppsFlyerLibDelegate {
233
277
} else {
234
278
analytics? . track ( name: " Organic Install " )
235
279
}
236
- } else {
237
280
}
238
-
239
281
}
240
282
241
283
public func onConversionDataFail( _ error: Error ) {
0 commit comments