@@ -92,44 +92,26 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
92
92
anonSessions [ JsonKey . matchedCriteriaId] = Int ( criteriaId)
93
93
let appName = Bundle . main. appPackageName ?? " "
94
94
notificationStateProvider. isNotificationsEnabled { isEnabled in
95
- if ( !appName. isEmpty && isEnabled) {
95
+ if !appName. isEmpty && isEnabled {
96
96
anonSessions [ JsonKey . mobilePushOptIn] = appName
97
97
}
98
-
99
- // store last update user event
100
- var updateUserEventIndex : Int ?
101
- var dataFields : [ AnyHashable : Any ] ?
102
- if let events = self . localStorage. anonymousUserEvents {
103
- // if there is an update user event, find the index of the last one
104
- if let eventIndex = events. lastIndex ( where: { dict in
105
- if let eventType = dict [ JsonKey . eventType] as? String , eventType == EventType . updateUser {
106
- return true
107
- }
108
- return false
109
- } ) {
110
- updateUserEventIndex = eventIndex
111
- var updateUserEvent = events [ eventIndex]
112
- updateUserEvent. removeValue ( forKey: JsonKey . eventType)
113
- //save update user event to data fields removing the event type
114
- dataFields = updateUserEvent
115
- }
116
- }
117
98
118
99
//track anon session for new user
119
- IterableAPI . implementation? . apiClient. trackAnonSession ( createdAt: IterableUtil . secondsFromEpoch ( for: self . dateProvider. currentDate) , withUserId: userId, dataFields: dataFields, requestJson: anonSessions) . onError { error in
120
- if ( error. httpStatusCode == 409 ) {
100
+ IterableAPI . implementation? . apiClient. trackAnonSession (
101
+ createdAt: IterableUtil . secondsFromEpoch ( for: self . dateProvider. currentDate) ,
102
+ withUserId: userId,
103
+ dataFields: self . localStorage. anonymousUserUpdate,
104
+ requestJson: anonSessions
105
+ ) . onError { error in
106
+ if error. httpStatusCode == 409 {
121
107
self . getAnonCriteria ( ) // refetch the criteria
122
108
}
123
109
} . onSuccess { success in
124
- //remove the update user event from local storage
125
- if var events = self . localStorage. anonymousUserEvents, let index = updateUserEventIndex {
126
- events. remove ( at: index)
127
- self . localStorage. anonymousUserEvents = events
128
- }
129
-
130
110
self . localStorage. userIdAnnon = userId
131
111
self . config. anonUserDelegate? . onAnonUserCreated ( userId: userId)
132
- IterableAPI . implementation? . setUserId ( userId, authToken: nil , successHandler: nil , failureHandler: nil , isAnon: true , identityResolution: nil )
112
+
113
+ IterableAPI . implementation? . setUserId ( userId, isAnon: true )
114
+
133
115
self . syncNonSyncedEvents ( )
134
116
}
135
117
}
@@ -144,37 +126,32 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
144
126
145
127
// Syncs locally saved data through track APIs
146
128
public func syncEvents( ) {
147
- let events = localStorage. anonymousUserEvents
148
- var successfulSyncedData : [ Int ] = [ ]
149
-
150
- if let _events = events {
151
- for var eventData in _events {
129
+ if let events = localStorage. anonymousUserEvents {
130
+ for var eventData in events {
152
131
if let eventType = eventData [ JsonKey . eventType] as? String {
153
132
eventData. removeValue ( forKey: JsonKey . eventType)
154
133
switch eventType {
155
134
case EventType . customEvent:
156
- IterableAPI . implementation? . track ( eventData [ JsonKey . eventName] as? String ?? " " , withBody: eventData, onSuccess: { result in
157
- successfulSyncedData. append ( eventData [ JsonKey . eventTimeStamp] as? Int ?? 0 )
158
- } )
135
+ IterableAPI . implementation? . track ( eventData [ JsonKey . eventName] as? String ?? " " , withBody: eventData)
159
136
break
160
137
case EventType . purchase:
161
138
var total = NSNumber ( value: 0 )
162
139
if let _total = NumberFormatter ( ) . number ( from: eventData [ JsonKey . Commerce. total] as! String ) {
163
140
total = _total
164
141
}
165
142
166
- IterableAPI . implementation? . trackPurchase ( total, items: convertCommerceItems ( from: eventData [ JsonKey . Commerce. items] as! [ [ AnyHashable : Any ] ] ) , dataFields: eventData [ JsonKey . dataFields] as? [ AnyHashable : Any ] , createdAt: eventData [ JsonKey . Body. createdAt] as? Int ?? 0 , onSuccess: { result in
167
- successfulSyncedData. append ( eventData [ JsonKey . eventTimeStamp] as? Int ?? 0 )
168
- } )
143
+ IterableAPI . implementation? . trackPurchase (
144
+ total,
145
+ items: convertCommerceItems ( from: eventData [ JsonKey . Commerce. items] as! [ [ AnyHashable : Any ] ] ) ,
146
+ dataFields: eventData [ JsonKey . dataFields] as? [ AnyHashable : Any ] ,
147
+ createdAt: eventData [ JsonKey . Body. createdAt] as? Int ?? 0
148
+ )
169
149
break
170
150
case EventType . updateCart:
171
- IterableAPI . implementation? . updateCart ( items: convertCommerceItems ( from: eventData [ JsonKey . Commerce. items] as! [ [ AnyHashable : Any ] ] ) , createdAt: eventData [ JsonKey . Body. createdAt] as? Int ?? 0 ,
172
- onSuccess: { result in
173
- successfulSyncedData. append ( eventData [ JsonKey . eventTimeStamp] as? Int ?? 0 )
174
- } )
175
- break
176
- case EventType . updateUser:
177
- IterableAPI . implementation? . updateUser ( eventData, mergeNestedObjects: false )
151
+ IterableAPI . implementation? . updateCart (
152
+ items: convertCommerceItems ( from: eventData [ JsonKey . Commerce. items] as! [ [ AnyHashable : Any ] ] ) ,
153
+ createdAt: eventData [ JsonKey . Body. createdAt] as? Int ?? 0
154
+ )
178
155
break
179
156
default :
180
157
break
@@ -193,15 +170,36 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
193
170
localStorage. anonymousUserEvents = nil
194
171
localStorage. anonymousSessions = nil
195
172
}
173
+
174
+ if var userUpdate = localStorage. anonymousUserUpdate {
175
+ if userUpdate [ JsonKey . eventType] is String {
176
+ userUpdate. removeValue ( forKey: JsonKey . eventType)
177
+ }
178
+
179
+ IterableAPI . implementation? . updateUser ( userUpdate, mergeNestedObjects: false )
180
+
181
+ localStorage. anonymousUserUpdate = nil
182
+ }
183
+
196
184
}
197
185
198
186
// Checks if criterias are being met and returns criteriaId if it matches the criteria.
199
187
private func evaluateCriteriaAndReturnID( ) -> String ? {
200
- guard let events = localStorage. anonymousUserEvents, let criteriaData = localStorage. criteriaData else {
201
- return nil
188
+ guard let criteriaData = localStorage. criteriaData else { return nil }
189
+
190
+ var events = [ [ AnyHashable: Any] ] ( )
191
+
192
+ if let anonymousUserEvents = localStorage. anonymousUserEvents {
193
+ events. append ( contentsOf: anonymousUserEvents)
194
+ }
195
+
196
+ if let userUpdate = localStorage. anonymousUserUpdate {
197
+ events. append ( userUpdate)
202
198
}
203
- let matchedCriteriaId = CriteriaCompletionChecker ( anonymousCriteria: criteriaData, anonymousEvents: events) . getMatchedCriteria ( )
204
- return matchedCriteriaId
199
+
200
+ guard events. count > 0 else { return nil }
201
+
202
+ return CriteriaCompletionChecker ( anonymousCriteria: criteriaData, anonymousEvents: events) . getMatchedCriteria ( )
205
203
}
206
204
207
205
// Gets the anonymous criteria
@@ -212,41 +210,51 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
212
210
}
213
211
214
212
// Stores event data locally
215
- private func storeEventData( type: String , data: [ AnyHashable : Any ] , shouldOverWrite: Bool ? = false ) {
213
+ private func storeEventData( type: String , data: [ AnyHashable : Any ] , shouldOverWrite: Bool = false ) {
214
+ // Early return if no AUT consent was given
216
215
if !self . localStorage. anonymousUsageTrack {
217
216
ITBInfo ( " AUT CONSENT NOT GIVEN - no events being stored " )
218
217
return
219
218
}
220
-
221
- let storedData = localStorage. anonymousUserEvents
222
- var eventsDataObjects : [ [ AnyHashable : Any ] ] = [ ]
223
-
224
- if let _storedData = storedData {
225
- eventsDataObjects = _storedData
226
- }
227
- var appendData = data
228
- appendData. setValue ( for: JsonKey . eventType, value: type)
229
- appendData. setValue ( for: JsonKey . eventTimeStamp, value: IterableUtil . secondsFromEpoch ( for: dateProvider. currentDate) ) // this we use as unique idenfier too
230
-
231
- if shouldOverWrite == true {
232
- let trackingType = type
233
- if let indexToUpdate = eventsDataObjects. firstIndex ( where: { $0 [ JsonKey . eventType] as? String == trackingType } ) {
234
- let dataToUpdate = eventsDataObjects [ indexToUpdate]
235
- eventsDataObjects [ indexToUpdate] = dataToUpdate. merging ( data) { ( _, new) in new }
236
- } else {
237
- eventsDataObjects. append ( appendData)
238
- }
219
+
220
+ if type == EventType . updateUser {
221
+ processAndStoreUserUpdate ( data: data)
239
222
} else {
240
- eventsDataObjects. append ( appendData)
241
- }
242
-
243
- let eventDataCount = eventsDataObjects. count
244
- if eventDataCount > config. eventThresholdLimit {
245
- eventsDataObjects = eventsDataObjects. suffix ( config. eventThresholdLimit)
223
+ processAndStoreEvent ( type: type, data: data)
246
224
}
247
- localStorage . anonymousUserEvents = eventsDataObjects
225
+
248
226
if let criteriaId = evaluateCriteriaAndReturnID ( ) {
249
227
createKnownUserIfCriteriaMatched ( criteriaId)
250
228
}
251
229
}
230
+
231
+ // Stores User Update data
232
+ private func processAndStoreUserUpdate( data: [ AnyHashable : Any ] ) {
233
+ var userUpdate = localStorage. anonymousUserUpdate ?? [ : ]
234
+
235
+ // Merge new data into userUpdate
236
+ userUpdate. merge ( data) { ( _, new) in new }
237
+
238
+ userUpdate. setValue ( for: JsonKey . eventType, value: EventType . updateUser)
239
+ userUpdate. setValue ( for: JsonKey . eventTimeStamp, value: IterableUtil . secondsFromEpoch ( for: dateProvider. currentDate) )
240
+
241
+ localStorage. anonymousUserUpdate = userUpdate
242
+ }
243
+
244
+ // Stores all other event data
245
+ private func processAndStoreEvent( type: String , data: [ AnyHashable : Any ] ) {
246
+ var eventsDataObjects : [ [ AnyHashable : Any ] ] = localStorage. anonymousUserEvents ?? [ ]
247
+
248
+ var newEventData = data
249
+ newEventData. setValue ( for: JsonKey . eventType, value: type)
250
+ newEventData. setValue ( for: JsonKey . eventTimeStamp, value: IterableUtil . secondsFromEpoch ( for: dateProvider. currentDate) ) // this we use as unique idenfier too
251
+
252
+ eventsDataObjects. append ( newEventData)
253
+
254
+ if eventsDataObjects. count > config. eventThresholdLimit {
255
+ eventsDataObjects = eventsDataObjects. suffix ( config. eventThresholdLimit)
256
+ }
257
+
258
+ localStorage. anonymousUserEvents = eventsDataObjects
259
+ }
252
260
}
0 commit comments