# iOS Push Integration Document
# Install SDK
pod 'ThinkingSDK', '3.0.1'
# I. FCM push
# 1.1 Report "Push ID"
- Track the FCM Token after calling TE login or switching accounts.
 
NSString *appId = @"app-id";
NSString *serverUrl = @"server-url";
TDConfig *tdConfig = [[TDConfig alloc] initWithAppId:appId serverUrl:serverUrl];
[TDAnalytics startAnalyticsWithConfig:tdConfig];
[[FIRMessaging messaging] tokenWithCompletion:^(NSString *token, NSError *error) {
      if (error != nil) {
        NSLog(@"Error getting FCM registration token: %@", error);
      } else {
        NSLog(@"FCM registration token: %@", token);
        [TDAnalytics userSet:@{@"fcm_token": token}];
      }
}];
# 1.2. Acquire Push Click Events
When tapping the push notification, the user can send the push click event in the push click callback of the system.
// use <UserNotifications/UserNotifications.h> framework
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    
    // "trackAppOpenNotification:" at the end of the article Appendix
    [self trackAppOpenNotification:userInfo];
    
    completionHandler();
}
# 1.3. Handle Push Messages
When tapping the push notification, the user can get push parameters in the push click callback of the system.
// use <UserNotifications/UserNotifications.h> framework
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    // process parameters. Function at the end of the article Appendix
    [self handleTEPushAction:userInfo];
    completionHandler();
}
# II. JPush
# 2.1 Report "Push ID"
- Track the Registration ID of JPush after calling TE login or switching accounts.
 
// Dafter login, report registrationID again
[TDAnalytics login:@"test_id"];
// "registrationID" is get from JPush SDK
[TDAnalytics userSet:@{@"jiguang_id": registrationID}];
- registrationIDCompletionHandler: track the Registration ID of URORA in the callback
 
// after SDK initialization, report the registrationID in callback
[JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
    [TDAnalytics userSet:@{@"jiguang_id": registrationID}];
}];
# 2.2. Acquire Push Click Events
//  for versions earlier than iOS10, click the notification callback
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [JPUSHService handleRemoteNotification:userInfo];
    // "trackAppOpenNotification:" at the end of the article Appendix
    [self trackAppOpenNotification:userInfo];
    
    completionHandler(UIBackgroundFetchResultNewData);
}
 
// for versions later than iOS10, click the notification callback
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler  API_AVAILABLE(ios(10.0)){
    // Required
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    // "trackAppOpenNotification:" at the end of the article Appendix
    [self trackAppOpenNotification:userInfo];
    // the system requires this method to be executed
    completionHandler();  
}
# 2.3. Handle Push Messages
// for versions earlier than iOS10, click the notification callback
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // Required, iOS 7 Support
    [JPUSHService handleRemoteNotification:userInfo];
    // "handleTEPushAction:" at the end of the article Appendix
    [self handleTEPushAction:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}
 
// for versions later than iOS10, click the notification callback
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler  API_AVAILABLE(ios(10.0)){
    // Required
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    // "handleTEPushAction:" at the end of the article Appendix
    [self handleTEPushAction:userInfo];
    // the system requires this method to be executed
    completionHandler();
}
# III. APNs
# 3.1 Report "Push ID"
- deviceToken is reported after login. The field type is string.
 
[TDAnalytics login:@"test_id"];
NSString *token = [self getDviceTokenDemoFunction];
[TDAnalytics userSet:@{ @"#apns_token": token }];
- Report user properties in the callback of the received registered deviceToken.
 
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *token;
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 13.0) {
        const unsigned *tokenBytes = [deviceToken bytes];
        token = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                 ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                 ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                 ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
    } else {
        token = [[deviceToken description] stringByReplacingOccurrencesOfString:@"<" withString:@""];
        token = [token stringByReplacingOccurrencesOfString:@">" withString:@""];
        token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    }
    
    [TDAnalytics userSet:@{ @"#apns_token": token }];
}
# 3.2 Acquire Push Click Events
// iOS 10 previous:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // "trackAppOpenNotification:" at the end of the article Appendix
    [self trackAppOpenNotification:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}
// iOS 10 after:use <UserNotifications/UserNotifications.h> framework
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    // "trackAppOpenNotification:" at the end of the article Appendix
    [self trackAppOpenNotification:userInfo];
    completionHandler();
}
# 3.3 Handle Push Messages
// for versions earlier than iOS10, click the notification callback
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
   // "handleTEPushAction:" at the end of the article Appendix
   [self handleTEPushAction:userInfo];
   completionHandler(UIBackgroundFetchResultNewData);
}
// for versions later than iOS10, click the notification callback
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    // "handleTEPushAction:" at the end of the article Appendix
    [self handleTEPushAction:userInfo];
    // the system requires this method to be executed
    completionHandler();
}
# Appendix
- trackAppOpenNotification method details
 
- (void)trackAppOpenNotification:(NSDictionary *)userInfo{
    @try {
        if ([userInfo.allKeys containsObject:@"te_extras"] && [userInfo[@"te_extras"] isKindOfClass:[NSString class]]) {
            NSData *jsonData = [userInfo[@"te_extras"] dataUsingEncoding:NSUTF8StringEncoding];
            NSError *err;
            NSDictionary *responseDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
            NSDictionary *opsReceiptProperties = responseDic[@"#ops_receipt_properties"];
            if ([opsReceiptProperties isKindOfClass:[NSString class]]) {
                NSString *opsStr = (NSString *)opsReceiptProperties;
                opsReceiptProperties = [NSJSONSerialization JSONObjectWithData:[opsStr dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&err];
            }
            if (opsReceiptProperties && [opsReceiptProperties isKindOfClass:[NSDictionary class]]) {
                NSMutableDictionary *pushProperties = [NSMutableDictionary dictionary];
                pushProperties[@"#ops_receipt_properties"] = opsReceiptProperties;
                [TDAnalytics track:@"te_ops_push_click" properties:pushProperties];
                [TDAnalytics flush];
            }
        }
    } @catch (NSException *exception) {
        
    }
}
- handleThinkingPushAction method details
 
- (void)handleTEPushAction:(NSDictionary *)userInfo{
    @try {
        NSString *jsonString = userInfo[@"te_extras"];
        NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
        NSError *error;
        NSDictionary *sfDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
        if (!sfDictionary || error) {
            return;
        }
        NSString *sf_landing_type = sfDictionary[@"ops_loading_type"];
        if ([sf_landing_type isEqualToString:@"OPEN_APP"]) {
        }
        else if ([sf_landing_type isEqualToString:@"OPEN_URL"]) {
           NSString *url = sfDictionary[@"ops_url"];
        }
        else if ([sf_landing_type isEqualToString:@"CUSTOMIZED"]) {
           NSString *customized = sfDictionary[@"ops_customized"];
        }
        
    } @catch (NSException *exception) {
        
    }
}
