// // APPdelegateModularForPush.m // jiaPei // // Created by 张嵘 on 2019/3/26. // Copyright © 2019 JCZ. All rights reserved. // #import "APPdelegateModularForPush.h" #import "RQAppEventAnnotation.h" /// 个推 #import /// iOS10 及以上需导入 UserNotifications.framework #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 #import #endif /// 个推开发者网站中申请App时,注册的AppId、AppKey、AppSecret #define kGtAppId @"gmSLqO5S6z9JfJ7hCDDYm1" #define kGtAppKey @"gKp3U30Zvv8OkKtM9N4cW8" #define kGtAppSecret @"JsWjt7BVSSARoLxF6jG7Q1" RQAppEventMod(APPdelegateModularForPush) @interface APPdelegateModularForPush () { NSString *pushType; NSString *pushID; } @end @implementation APPdelegateModularForPush - (NSInteger)moduleLevel { return 3; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self initMudule]; // [self destroyModule]; return YES; } - (void)initMudule { //暂时-屏蔽个推 // // 通过个推平台分配的appId、 appKey 、appSecret 启动SDK,注:该方法需要在主线程中调用 // dispatch_async(dispatch_get_main_queue(), ^{ // [GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self launchingOptions:nil]; // }); // 注册 通知(本地/远程) [self registerRemoteNotification]; #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_10_0 //这里即使不判断系统版本,后面也做了避免消息重复处理。didReceiveNotificationResponse 统一处理 //远程通知 if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) { //关于这个方法远程和进程不一样 一个是userinfo字典。一个是本地通知 NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; //这里不用判断重复消息 NSString *msgId = [userInfo[@"_gmid_"] componentsSeparatedByString:@":"][1]; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:msgId forKey:@"remoteNotifymsgId"]; [userDefaults synchronize]; NSString *jsonStr = userInfo[@"payload"]; if ([jsonStr length] != 0) { NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding]; if (data) { NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]]; pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]]; //1 驾考头条推送 2 新闻类型 3 话题相关信息 4 系统信息 5 预约相关 教练列表 if ([pushType integerValue]>=1 && [pushType integerValue]<=5) { [self gotoPush]; }else{ //其它信息 [self gotoLoad]; [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]]; } return YES; } } } #endif } #pragma mark 推送注册 /** 注册 APNs */ - (void)registerRemoteNotification { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) { if (!error) { NSLog(@"request authorization succeeded!(iOS >= 10.0)"); } }]; [[UIApplication sharedApplication] registerForRemoteNotifications]; #elif defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerForRemoteNotifications]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; #else UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge); [[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type]; #endif } /** 远程通知注册成功委托 */ - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; NSLog(@"\n>>>[DeviceToken Success]:%@\n\n", token); // 向个推服务器注册deviceToken // [GeTuiSdk registerDeviceToken:token]; } /** 远程通知注册失败委托 */ - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { // NSLog(@"FailToRegisterForRemoteNotificationsWithError:%@",error); } //iOS7.0 以后支持 APP 后台刷新数据,会回调 performFetchWithCompletionHandler 接口。为保证个推SDK的数据刷新,需在该回调接口中调用[GeTuiSdk resume]方法帮助个推 SDK 刷新数据。 - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { /// Background Fetch 恢复SDK 运行 //[GeTuiSdk resume]; completionHandler(UIBackgroundFetchResultNewData); } #pragma mark - iOS < 10 //处理 APNs 通知点击事件,统计有效用户点击数- (App运行在后台/App运行在前台) and apns静默推送消息处理 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { NSLog(@"didReceiveRemoteNotification and iOS<10"); if ([application isKindOfClass:[NSDictionary class]]) { // 将收到的APNs信息传给个推统计 //[GeTuiSdk handleRemoteNotification:(NSDictionary *)application]; completionHandler(UIBackgroundFetchResultNewData); [self remoteNotificationDealWithDic:(NSDictionary *)application]; } else { // 将收到的APNs信息传给个推统计 //[GeTuiSdk handleRemoteNotification:userInfo]; completionHandler(UIBackgroundFetchResultNewData); [self remoteNotificationDealWithDic:userInfo]; } } #pragma mark iOS > 10 //对于iOS 10 及以后版本,为处理 APNs 通知点击,统计有效用户点击数,需先添加 UNUserNotificationCenterDelegate #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 // iOS 10: App在前台获取到通知 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { NSLog(@"willPresentNotification and iOS>10前台获取到通知:%@", notification.request.content.userInfo); // 根据APP需要,判断是否要提示用户Badge、Sound、Alert completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert); } // iOS 10: 点击通知进入App时触发,在该方法内统计有效用户点击数 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { NSLog(@"didReceiveNotification and iOS>10后台获取到通知:%@", response.notification.request.content.userInfo); // [ GTSdk ]:将收到的APNs信息传给个推统计 //[GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo]; completionHandler(); //此处表述程序由远程通知启动打开(不是点击桌面icon) NSDictionary* userInfo = response.notification.request.content.userInfo; [self remoteNotificationDealWithDic:userInfo]; } #endif #pragma mark - 个推相关方法 /** SDK启动成功返回cid 在这里将cid给自己的服务器 */ - (void)GeTuiSdkDidRegisterClient:(NSString *)clientId { //个推SDK已注册,返回clientId //NSLog(@"\n>>>[GeTuiSdk RegisterClient]:%@\n\n", clientId); //NSLog(@"获取推送token执行"); myDelegate.token = clientId; NSString *tokenPass = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"apnsToken.plist"]; if (![myDelegate.token writeToFile:tokenPass atomically:YES encoding:NSUTF8StringEncoding error:nil]) { NSLog(@"保存失败"); } //注册成功,将deviceToken保存到应用服务器数据库中 // [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""] // stringByReplacingOccurrencesOfString:@">" withString:@""] // stringByReplacingOccurrencesOfString:@" " withString:@""] } /** SDK遇到错误回调 */ - (void)GeTuiSdkDidOccurError:(NSError *)error { //个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。 // NSLog(@"\n>>>[GexinSdk error]:%@\n\n", [error localizedDescription]); } /** SDK收到透传消息回调 *//*(个推-客户端)*/ //只要你不是点通知窗口进来的,and发消息的时候有选择离线的情况,都会进这里---by@lee - (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId { //收到个推消息 if (payloadData) { NSString * payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding]; NSLog(@"GeTuiSdkDidReceivepayloadMsg:%@",payloadMsg); //判断是否被处理过[即发送离线消息的时候,会走apns+个推sdk(有效期内)] //ps:这里处理之后不做存档操作,保证点击通知栏的时候可以”再处理一次“ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSString *oldmsgId = [userDefaults objectForKey:@"remoteNotifymsgId"]; if ([oldmsgId isEqualToString:msgId]) { return; } NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:payloadData options:NSJSONReadingMutableContainers error:nil]; if (payloadDic.count == 0) { return; } pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]]; pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]]; if ([pushType integerValue]>=1 && [pushType integerValue]<=5) { UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:payloadDic[@"title"] message:payloadDic[@"body"] preferredStyle:UIAlertControllerStyleAlert]; [alertFind addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]]; [alertFind addAction:[UIAlertAction actionWithTitle:@"前往" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { [self gotoPush]; }]]; [self.window.rootViewController presentViewController:alertFind animated:true completion:nil]; }else{ //其它信息 [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]]; } } } #pragma mark 远程通知的数据处理 -(void)remoteNotificationDealWithDic:(NSDictionary *)userInfo{ /* { "_ge_" = 1; "_gmid_" = "OSL-0818_bJ6zVRy8cC6JsflZOYPXO9:965f14a1051748c4a48f9db2437362e5:d48422d462d2bcf0b9d962f150b235b9"; "_gurl_" = "sdk.open.extension.getui.com:8123"; aps = { alert = { body = "\U60a8\U9a7e\U6821\U6709\U8f66\U8f86\U7ec8\U7aef\U62a5\U8b66\U9700\U89e3\U9664\Uff0c\U8bf7\U67e5\U770b\U5e76\U5904\U7406"; title = "\U544a\U8b66\U6d88\U606f"; }; badge = 2; category = "button\U663e\U793a"; "content-available" = 1; "mutable-content" = 1; sound = default; }; payload = "{\"title\":\"\U544a\U8b66\U6d88\U606f\",\"code\":\"1\",\"body\":\"\U60a8\U9a7e\U6821\U6709\U8f66\U8f86\U7ec8\U7aef\U62a5\U8b66\U9700\U89e3\U9664\Uff0c\U8bf7\U67e5\U770b\U5e76\U5904\U7406\,\"id\":\"2\"}"; } */ // _gmid_对应-- taskId msgId clientID //这里使用msgid判断是否被处理【不过似乎应该用taskid?@lee,幻想着一个任务多条消息] NSString *msgId = [userInfo[@"_gmid_"] componentsSeparatedByString:@":"][1]; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSString *oldMsgId = [userDefaults objectForKey:@"remoteNotifymsgId"]; if ([msgId isEqualToString:oldMsgId]) { return; } //开始处理 [userDefaults setObject:msgId forKey:@"remoteNotifymsgId"]; [userDefaults synchronize]; NSString *jsonStr = userInfo[@"payload"]; if ([jsonStr length] == 0) { return; } NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; if (payloadDic) { pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]]; pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]]; //1 驾考头条推送 2 新闻类型 3 话题相关信息 4 系统信息 5 预约相关 教练列表 if ([pushType integerValue]>=1 && [pushType integerValue]<=6) { [self gotoPush]; }else{ //其它信息 [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]]; } }else { } } -(void)showMsgByArertWithTitle:(NSString *)title message:(NSString *)message{ if (message.length == 0) { return; } //其它信息 UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; [alertFind addAction:[UIAlertAction actionWithTitle:@"我知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]]; [self.window.rootViewController presentViewController:alertFind animated:true completion:nil]; } #pragma mark 推送相关跳转 - (void)gotoPush { //1 驾考头条推送 2 新闻类型 3 话题相关信息 4 系统信息 5 预约相关 教练列表 //新闻和驾考头条是一样的 switch ([pushType integerValue]) { case 1: [self goToJKTT]; break; case 2: [self goToJKTT]; break; case 3: [self goToTopic]; break; case 4: [self goToSystemNews]; break; case 5: [self goToAppoint]; break; case 6: [self gotoMyMessage]; break; default: [self goToNews]; break; } } - (void)goToJKTT { } - (void)goToSystemNews { } - (void)goToNews { } - (void)goToTopic { } - (void)goToAppoint { } - (void)gotoMyMessage { } #pragma mark - 监测程序状态 //程序复原 - (void)applicationDidBecomeActive:(UIApplication *)application { //删除程序小红点 //[GeTuiSdk resetBadge]; //重置角标计数 [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; // APP 清空角标 if (myDelegate.timer) { [myDelegate.timer setFireDate:[NSDate distantPast]]; } myDelegate.isBackgroundTask = NO; } @end