@@ -45,7 +45,7 @@ @implementation SEGKahunaIntegration
45
45
46
46
+ (void )load {
47
47
[SEGAnalytics registerIntegration: self withIdentifier: @" Kahuna" ];
48
-
48
+
49
49
// When this class loads we will register for the 'UIApplicationDidFinishLaunchingNotification' notification.
50
50
// To receive the notification we will use the SEGKahunaPushMonitor singleton instance.
51
51
[[NSNotificationCenter defaultCenter ] addObserver: [SEGKahunaPushMonitor sharedInstance ]
@@ -60,7 +60,7 @@ - (id)init {
60
60
self.name = @" Kahuna" ;
61
61
self.valid = NO ;
62
62
self.initialized = NO ;
63
-
63
+
64
64
_kahunaCredentialsKeys = [NSSet setWithObjects: KAHUNA_CREDENTIAL_USERNAME,
65
65
KAHUNA_CREDENTIAL_EMAIL,
66
66
KAHUNA_CREDENTIAL_FACEBOOK,
@@ -85,11 +85,11 @@ - (void)start {
85
85
[KahunaAnalytics handleNotification: [SEGKahunaPushMonitor sharedInstance ].pushInfo withApplicationState: [SEGKahunaPushMonitor sharedInstance ].applicationState];
86
86
[SEGKahunaPushMonitor sharedInstance ].pushInfo = nil ;
87
87
}
88
-
88
+
89
89
[SEGKahunaPushMonitor sharedInstance ].kahunaInitialized = TRUE ;
90
90
}
91
91
}
92
-
92
+
93
93
[super start ];
94
94
}
95
95
@@ -106,12 +106,12 @@ - (void)identify:(NSString *)userId traits:(NSDictionary *)traits options:(NSDic
106
106
if (KAHUNA_NOT_STRING_NULL_EMPTY (userId)) {
107
107
[KahunaAnalytics setUserCredentialsWithKey: KAHUNA_CREDENTIAL_USER_ID andValue: userId];
108
108
}
109
-
109
+
110
110
// We will go through each of the above keys, and try to see if the traits has that key. If it does, then we will add the key:value as a credential.
111
111
// All other traits is being tracked as an attribute.
112
112
for (NSString *eachKey in traits) {
113
113
if (!KAHUNA_NOT_STRING_NULL_EMPTY (eachKey)) continue ;
114
-
114
+
115
115
NSString *eachValue = [traits objectForKey: eachKey];
116
116
if (KAHUNA_NOT_STRING_NULL_EMPTY (eachValue)) {
117
117
// Check if this is a Kahuna credential key.
@@ -136,7 +136,7 @@ - (void)identify:(NSString *)userId traits:(NSDictionary *)traits options:(NSDic
136
136
}
137
137
}
138
138
}
139
-
139
+
140
140
// Track the attributes if we have any items in it.
141
141
if (attributes.count > 0 ) {
142
142
[KahunaAnalytics setUserAttributes: attributes];
@@ -155,30 +155,30 @@ - (void)track:(NSString *)event properties:(NSDictionary *)properties options:(N
155
155
} else if ([value isKindOfClass: [NSNumber class ]]) {
156
156
quantity = value;
157
157
}
158
-
158
+
159
159
break ;
160
160
}
161
161
}
162
-
162
+
163
163
// Get the count and value from quantity and revenue.
164
164
long value = (long ) ([revenue doubleValue ] * 100 );
165
165
long count = [quantity longValue ];
166
-
166
+
167
167
if (count + value > 0 ) {
168
168
[KahunaAnalytics trackEvent: event withCount: count andValue: value];
169
169
} else {
170
170
[KahunaAnalytics trackEvent: event];
171
171
}
172
-
172
+
173
173
NSMutableDictionary *attributes = [[NSMutableDictionary alloc ] init ];
174
174
NSMutableDictionary *lowerCaseKeyProperties = [[NSMutableDictionary alloc ] init ];
175
-
175
+
176
176
// Lower case all the keys and copy over the properties into a new dictionary.
177
177
for (NSString *eachKey in properties) {
178
178
if (!KAHUNA_NOT_STRING_NULL_EMPTY (eachKey)) continue ;
179
179
[lowerCaseKeyProperties setValue: properties[eachKey] forKey: [eachKey lowercaseString ]];
180
180
}
181
-
181
+
182
182
if ([event caseInsensitiveCompare: KAHUNA_VIEWED_PRODUCT_CATEGORY] == NSOrderedSame) {
183
183
[self addViewedProductCategoryElements: &attributes fromProperties: lowerCaseKeyProperties];
184
184
} else if ([event caseInsensitiveCompare: KAHUNA_VIEWED_PRODUCT] == NSOrderedSame) {
@@ -188,7 +188,7 @@ - (void)track:(NSString *)event properties:(NSDictionary *)properties options:(N
188
188
} else if ([event caseInsensitiveCompare: KAHUNA_COMPLETED_ORDER] == NSOrderedSame) {
189
189
[self addCompletedOrderElements: &attributes fromProperties: lowerCaseKeyProperties];
190
190
}
191
-
191
+
192
192
// If we have collected any attributes, then we will call the setUserAttributes API
193
193
if (attributes.count > 0 ) {
194
194
[KahunaAnalytics setUserAttributes: attributes];
@@ -207,7 +207,7 @@ - (void) addViewedProductCategoryElements:(NSMutableDictionary*__autoreleasing*)
207
207
if (aryOfCategoriesViewed.count > 50 ) {
208
208
[aryOfCategoriesViewed removeObjectAtIndex: 0 ]; // Remove the first object.
209
209
}
210
-
210
+
211
211
[aryOfCategoriesViewed addObject: value];
212
212
[(*attributes) setValue: [aryOfCategoriesViewed componentsJoinedByString: @" ," ] forKey: KAHUNA_CATEGORIES_VIEWED];
213
213
}
@@ -226,7 +226,7 @@ - (void) addViewedProductElements:(NSMutableDictionary*__autoreleasing*) attribu
226
226
if (KAHUNA_NOT_STRING_NULL_EMPTY (kname)) {
227
227
[(*attributes) setValue: kname forKey: KAHUNA_LAST_PRODUCT_VIEWED_NAME];
228
228
}
229
-
229
+
230
230
[self addViewedProductCategoryElements: attributes fromProperties: properties];
231
231
}
232
232
@@ -235,12 +235,12 @@ - (void) addAddedProductElements:(NSMutableDictionary*__autoreleasing*) attribut
235
235
if (KAHUNA_NOT_STRING_NULL_EMPTY (kname)) {
236
236
[(*attributes) setValue: kname forKey: KAHUNA_LAST_PRODUCT_ADDED_TO_CART_NAME];
237
237
}
238
-
238
+
239
239
id category = properties [KAHUNA_CATEGORY];
240
240
if (!KAHUNA_NOT_STRING_NULL_EMPTY (category)) {
241
241
category = KAHUNA_NONE;
242
242
}
243
-
243
+
244
244
[(*attributes) setValue: category forKey: KAHUNA_LAST_PRODUCT_ADDED_TO_CART_CATEGORY];
245
245
}
246
246
@@ -254,7 +254,7 @@ - (void) addCompletedOrderElements:(NSMutableDictionary*__autoreleasing*) attrib
254
254
}
255
255
256
256
- (void )screen : (NSString *)screenTitle properties : (NSDictionary *)properties options : (NSDictionary *)options {
257
- BOOL trackAllPages = [[self .settings objectForKey: @" trackAllPages" ] boolValue ];
257
+ BOOL trackAllPages = [( NSNumber *) [self .settings objectForKey: @" trackAllPages" ] boolValue ];
258
258
if (trackAllPages && KAHUNA_NOT_STRING_NULL_EMPTY (screenTitle)) {
259
259
// Track the screen view as an event.
260
260
[self track: SEGEventNameForScreenTitle (screenTitle) properties: properties options: options];
@@ -291,7 +291,7 @@ - (void) didFinishLaunching:(NSNotification*) notificationPayload {
291
291
[SEGKahunaPushMonitor sharedInstance ].pushInfo = remoteNotification;
292
292
[SEGKahunaPushMonitor sharedInstance ].applicationState = UIApplicationStateInactive;
293
293
}
294
-
294
+
295
295
// We will also swizzle the app delegate methods now. We need this so that we can intercept the registration for device token
296
296
// and a push being received when the app is in foreground or background.
297
297
[self swizzleAppDelegateMethods ];
@@ -312,11 +312,11 @@ - (void) swizzleAppDelegateMethods
312
312
{
313
313
Method methodSegmentWrapper = class_getInstanceMethod ([self class ], selector);
314
314
const char *methodTypeEncoding = method_getTypeEncoding (methodSegmentWrapper);
315
-
315
+
316
316
IMP implementationSegmentWrapper = class_getMethodImplementation ([self class ], selector);
317
317
class_addMethod ([[UIApplication sharedApplication ].delegate class ], selector, implementationSegmentWrapper, methodTypeEncoding);
318
318
}
319
-
319
+
320
320
// ####### didReceiveRemoteNotification #######
321
321
selector = @selector (application:didReceiveRemoteNotification: );
322
322
if ([[UIApplication sharedApplication ].delegate respondsToSelector: selector])
@@ -327,18 +327,18 @@ - (void) swizzleAppDelegateMethods
327
327
{
328
328
Method methodSegmentWrapper = class_getInstanceMethod ([self class ], selector);
329
329
const char *methodTypeEncoding = method_getTypeEncoding (methodSegmentWrapper);
330
-
330
+
331
331
IMP implementationSegmentWrapper = class_getMethodImplementation ([self class ], selector);
332
332
class_addMethod ([[UIApplication sharedApplication ].delegate class ], selector, implementationSegmentWrapper, methodTypeEncoding);
333
333
}
334
-
334
+
335
335
// ####### didReceiveRemoteNotification:fetchCompletionHandler #######
336
336
selector = @selector (application:didReceiveRemoteNotification:fetchCompletionHandler: );
337
337
if ([[UIApplication sharedApplication ].delegate respondsToSelector: selector])
338
338
{
339
339
selOriginalApplicationDidReceiveRemoteNotificationWithFetchCompletionHandler = (void (*)(id , SEL , id , id , void (^)(UIBackgroundFetchResult result))) [[[UIApplication sharedApplication ].delegate class ] instanceMethodForSelector: selector];
340
340
}
341
-
341
+
342
342
// ####### handleActionWithIdentifier:forRemoteNotification:completionHandler #######
343
343
selector = @selector (application:handleActionWithIdentifier:forRemoteNotification:completionHandler: );
344
344
if ([[UIApplication sharedApplication ].delegate respondsToSelector: selector])
@@ -349,38 +349,38 @@ - (void) swizzleAppDelegateMethods
349
349
{
350
350
Method methodSegmentWrapper = class_getInstanceMethod ([self class ], selector);
351
351
const char *methodTypeEncoding = method_getTypeEncoding (methodSegmentWrapper);
352
-
352
+
353
353
IMP implementationSegmentWrapper = class_getMethodImplementation ([self class ], selector);
354
354
addedMethodHandleActionWithIdentifierWithFetchCompletionHandler = class_addMethod ([[UIApplication sharedApplication ].delegate class ], selector, implementationSegmentWrapper, methodTypeEncoding);
355
355
}
356
-
356
+
357
357
// Swizzle the methods only if we got the original Application selector. Otherwise no point doing the swizzling.
358
358
Method methodSegmentWrapper = nil ;
359
359
Method methodHostApp = nil ;
360
-
360
+
361
361
// Swizzling didFailToRegisterForRemoteNotificationsWithError
362
362
if (selOriginalApplicationDidFailToRegisterForRemoteNotificationsWithError)
363
363
{
364
364
methodSegmentWrapper = class_getInstanceMethod ([self class ], @selector (application:didFailToRegisterForRemoteNotificationsWithError: ));
365
365
methodHostApp = class_getInstanceMethod ([[UIApplication sharedApplication ].delegate class ], @selector (application:didFailToRegisterForRemoteNotificationsWithError: ));
366
366
method_exchangeImplementations (methodSegmentWrapper, methodHostApp);
367
367
}
368
-
368
+
369
369
// Swizzling didReceiveRemoteNotification
370
370
if (selOriginalApplicationDidReceiveRemoteNotification)
371
371
{
372
372
methodSegmentWrapper = class_getInstanceMethod ([self class ], @selector (application:didReceiveRemoteNotification: ));
373
373
methodHostApp = class_getInstanceMethod ([[UIApplication sharedApplication ].delegate class ], @selector (application:didReceiveRemoteNotification: ));
374
374
method_exchangeImplementations (methodSegmentWrapper, methodHostApp);
375
375
}
376
-
376
+
377
377
if (selOriginalApplicationDidReceiveRemoteNotificationWithFetchCompletionHandler)
378
378
{
379
379
methodSegmentWrapper = class_getInstanceMethod ([self class ], @selector (application:didReceiveRemoteNotification:fetchCompletionHandler: ));
380
380
methodHostApp = class_getInstanceMethod ([[UIApplication sharedApplication ].delegate class ], @selector (application:didReceiveRemoteNotification:fetchCompletionHandler: ));
381
381
method_exchangeImplementations (methodSegmentWrapper, methodHostApp);
382
382
}
383
-
383
+
384
384
selector = @selector (application:handleActionWithIdentifier:forRemoteNotification:completionHandler: );
385
385
if (selOriginalApplicationHandleActionWithIdentifierWithFetchCompletionHandler)
386
386
{
@@ -400,7 +400,7 @@ - (void) application:(UIApplication *)application didFailToRegisterForRemoteNoti
400
400
if ([SEGKahunaPushMonitor sharedInstance ].kahunaInitialized ) {
401
401
[KahunaAnalytics handleNotificationRegistrationFailure: error];
402
402
}
403
-
403
+
404
404
if (selOriginalApplicationDidFailToRegisterForRemoteNotificationsWithError)
405
405
{
406
406
selOriginalApplicationDidFailToRegisterForRemoteNotificationsWithError ([UIApplication sharedApplication ].delegate ,
0 commit comments