APPdelegateModularForPush.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. //
  2. // APPdelegateModularForPush.m
  3. // jiaPei
  4. //
  5. // Created by 张嵘 on 2019/3/26.
  6. // Copyright © 2019 JCZ. All rights reserved.
  7. //
  8. #import "APPdelegateModularForPush.h"
  9. #import "RQAppEventAnnotation.h"
  10. /// 个推
  11. #import <GTSDK/GeTuiSdk.h>
  12. /// iOS10 及以上需导入 UserNotifications.framework
  13. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  14. #import <UserNotifications/UserNotifications.h>
  15. #endif
  16. /// 个推开发者网站中申请App时,注册的AppId、AppKey、AppSecret
  17. #define kGtAppId @"gmSLqO5S6z9JfJ7hCDDYm1"
  18. #define kGtAppKey @"gKp3U30Zvv8OkKtM9N4cW8"
  19. #define kGtAppSecret @"JsWjt7BVSSARoLxF6jG7Q1"
  20. RQAppEventMod(APPdelegateModularForPush)
  21. @interface APPdelegateModularForPush () <GeTuiSdkDelegate, UNUserNotificationCenterDelegate> {
  22. NSString *pushType;
  23. NSString *pushID;
  24. }
  25. @end
  26. @implementation APPdelegateModularForPush
  27. - (NSInteger)moduleLevel {
  28. return 3;
  29. }
  30. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  31. [self initMudule];
  32. // [self destroyModule];
  33. return YES;
  34. }
  35. - (void)initMudule {
  36. // 通过个推平台分配的appId、 appKey 、appSecret 启动SDK,注:该方法需要在主线程中调用
  37. dispatch_async(dispatch_get_main_queue(), ^{
  38. [GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self launchingOptions:nil];
  39. });
  40. // 注册 通知(本地/远程)
  41. [self registerRemoteNotification];
  42. #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_10_0
  43. //这里即使不判断系统版本,后面也做了避免消息重复处理。didReceiveNotificationResponse 统一处理
  44. //远程通知
  45. if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey])
  46. {
  47. //关于这个方法远程和进程不一样 一个是userinfo字典。一个是本地通知
  48. NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
  49. //这里不用判断重复消息
  50. NSString *msgId = [userInfo[@"_gmid_"] componentsSeparatedByString:@":"][1];
  51. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  52. [userDefaults setObject:msgId forKey:@"remoteNotifymsgId"];
  53. [userDefaults synchronize];
  54. NSString *jsonStr = userInfo[@"payload"];
  55. if ([jsonStr length] != 0) {
  56. NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
  57. if (data) {
  58. NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
  59. pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]];
  60. pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]];
  61. //1 驾考头条推送 2 新闻类型 3 话题相关信息 4 系统信息 5 预约相关 教练列表
  62. if ([pushType integerValue]>=1 && [pushType integerValue]<=5) {
  63. [self gotoPush];
  64. }else{
  65. //其它信息
  66. [self gotoLoad];
  67. [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]];
  68. }
  69. return YES;
  70. }
  71. }
  72. }
  73. #endif
  74. }
  75. #pragma mark 推送注册
  76. /** 注册 APNs */
  77. - (void)registerRemoteNotification {
  78. #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
  79. UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  80. center.delegate = self;
  81. [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) {
  82. if (!error) {
  83. NSLog(@"request authorization succeeded!(iOS >= 10.0)");
  84. }
  85. }];
  86. [[UIApplication sharedApplication] registerForRemoteNotifications];
  87. #elif defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
  88. UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
  89. UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
  90. [[UIApplication sharedApplication] registerForRemoteNotifications];
  91. [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
  92. #else
  93. UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge);
  94. [[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type];
  95. #endif
  96. }
  97. /** 远程通知注册成功委托 */
  98. - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  99. NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
  100. token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
  101. NSLog(@"\n>>>[DeviceToken Success]:%@\n\n", token);
  102. // 向个推服务器注册deviceToken
  103. [GeTuiSdk registerDeviceToken:token];
  104. }
  105. /** 远程通知注册失败委托 */
  106. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  107. // NSLog(@"FailToRegisterForRemoteNotificationsWithError:%@",error);
  108. }
  109. //iOS7.0 以后支持 APP 后台刷新数据,会回调 performFetchWithCompletionHandler 接口。为保证个推SDK的数据刷新,需在该回调接口中调用[GeTuiSdk resume]方法帮助个推 SDK 刷新数据。
  110. - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  111. /// Background Fetch 恢复SDK 运行
  112. [GeTuiSdk resume];
  113. completionHandler(UIBackgroundFetchResultNewData);
  114. }
  115. #pragma mark - iOS < 10
  116. //处理 APNs 通知点击事件,统计有效用户点击数- (App运行在后台/App运行在前台) and apns静默推送消息处理
  117. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  118. NSLog(@"didReceiveRemoteNotification and iOS<10");
  119. if ([application isKindOfClass:[NSDictionary class]]) {
  120. // 将收到的APNs信息传给个推统计
  121. [GeTuiSdk handleRemoteNotification:(NSDictionary *)application];
  122. completionHandler(UIBackgroundFetchResultNewData);
  123. [self remoteNotificationDealWithDic:(NSDictionary *)application];
  124. } else {
  125. // 将收到的APNs信息传给个推统计
  126. [GeTuiSdk handleRemoteNotification:userInfo];
  127. completionHandler(UIBackgroundFetchResultNewData);
  128. [self remoteNotificationDealWithDic:userInfo];
  129. }
  130. }
  131. #pragma mark iOS > 10
  132. //对于iOS 10 及以后版本,为处理 APNs 通知点击,统计有效用户点击数,需先添加 UNUserNotificationCenterDelegate
  133. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  134. // iOS 10: App在前台获取到通知
  135. - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  136. NSLog(@"willPresentNotification and iOS>10前台获取到通知:%@", notification.request.content.userInfo);
  137. // 根据APP需要,判断是否要提示用户Badge、Sound、Alert
  138. completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
  139. }
  140. // iOS 10: 点击通知进入App时触发,在该方法内统计有效用户点击数
  141. - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
  142. NSLog(@"didReceiveNotification and iOS>10后台获取到通知:%@", response.notification.request.content.userInfo);
  143. // [ GTSdk ]:将收到的APNs信息传给个推统计
  144. [GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo];
  145. completionHandler();
  146. //此处表述程序由远程通知启动打开(不是点击桌面icon)
  147. NSDictionary* userInfo = response.notification.request.content.userInfo;
  148. [self remoteNotificationDealWithDic:userInfo];
  149. }
  150. #endif
  151. #pragma mark - 个推相关方法
  152. /** SDK启动成功返回cid 在这里将cid给自己的服务器 */
  153. - (void)GeTuiSdkDidRegisterClient:(NSString *)clientId {
  154. //个推SDK已注册,返回clientId
  155. //NSLog(@"\n>>>[GeTuiSdk RegisterClient]:%@\n\n", clientId);
  156. //NSLog(@"获取推送token执行");
  157. myDelegate.token = clientId;
  158. NSString *tokenPass = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"apnsToken.plist"];
  159. if (![myDelegate.token writeToFile:tokenPass atomically:YES encoding:NSUTF8StringEncoding error:nil]) {
  160. NSLog(@"保存失败");
  161. }
  162. //注册成功,将deviceToken保存到应用服务器数据库中
  163. // [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""]
  164. // stringByReplacingOccurrencesOfString:@">" withString:@""]
  165. // stringByReplacingOccurrencesOfString:@" " withString:@""]
  166. }
  167. /** SDK遇到错误回调 */
  168. - (void)GeTuiSdkDidOccurError:(NSError *)error {
  169. //个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。
  170. // NSLog(@"\n>>>[GexinSdk error]:%@\n\n", [error localizedDescription]);
  171. }
  172. /** SDK收到透传消息回调 *//*(个推-客户端)*/
  173. //只要你不是点通知窗口进来的,and发消息的时候有选择离线的情况,都会进这里---by@lee
  174. - (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
  175. //收到个推消息
  176. if (payloadData) {
  177. NSString * payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding];
  178. NSLog(@"GeTuiSdkDidReceivepayloadMsg:%@",payloadMsg);
  179. //判断是否被处理过[即发送离线消息的时候,会走apns+个推sdk(有效期内)]
  180. //ps:这里处理之后不做存档操作,保证点击通知栏的时候可以”再处理一次“
  181. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  182. NSString *oldmsgId = [userDefaults objectForKey:@"remoteNotifymsgId"];
  183. if ([oldmsgId isEqualToString:msgId]) {
  184. return;
  185. }
  186. NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:payloadData options:NSJSONReadingMutableContainers error:nil];
  187. if (payloadDic.count == 0) {
  188. return;
  189. }
  190. pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]];
  191. pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]];
  192. if ([pushType integerValue]>=1 && [pushType integerValue]<=5) {
  193. UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:payloadDic[@"title"] message:payloadDic[@"body"] preferredStyle:UIAlertControllerStyleAlert];
  194. [alertFind addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  195. }]];
  196. [alertFind addAction:[UIAlertAction actionWithTitle:@"前往" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
  197. [self gotoPush];
  198. }]];
  199. [self.window.rootViewController presentViewController:alertFind animated:true completion:nil];
  200. }else{
  201. //其它信息
  202. [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]];
  203. }
  204. }
  205. }
  206. #pragma mark 远程通知的数据处理
  207. -(void)remoteNotificationDealWithDic:(NSDictionary *)userInfo{
  208. /*
  209. {
  210. "_ge_" = 1;
  211. "_gmid_" = "OSL-0818_bJ6zVRy8cC6JsflZOYPXO9:965f14a1051748c4a48f9db2437362e5:d48422d462d2bcf0b9d962f150b235b9";
  212. "_gurl_" = "sdk.open.extension.getui.com:8123";
  213. aps = {
  214. alert = {
  215. body = "\U60a8\U9a7e\U6821\U6709\U8f66\U8f86\U7ec8\U7aef\U62a5\U8b66\U9700\U89e3\U9664\Uff0c\U8bf7\U67e5\U770b\U5e76\U5904\U7406";
  216. title = "\U544a\U8b66\U6d88\U606f";
  217. };
  218. badge = 2;
  219. category = "button\U663e\U793a";
  220. "content-available" = 1;
  221. "mutable-content" = 1;
  222. sound = default;
  223. };
  224. 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\"}";
  225. }
  226. */
  227. // _gmid_对应-- taskId msgId clientID
  228. //这里使用msgid判断是否被处理【不过似乎应该用taskid?@lee,幻想着一个任务多条消息]
  229. NSString *msgId = [userInfo[@"_gmid_"] componentsSeparatedByString:@":"][1];
  230. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  231. NSString *oldMsgId = [userDefaults objectForKey:@"remoteNotifymsgId"];
  232. if ([msgId isEqualToString:oldMsgId]) {
  233. return;
  234. }
  235. //开始处理
  236. [userDefaults setObject:msgId forKey:@"remoteNotifymsgId"];
  237. [userDefaults synchronize];
  238. NSString *jsonStr = userInfo[@"payload"];
  239. if ([jsonStr length] == 0) {
  240. return;
  241. }
  242. NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
  243. NSDictionary * payloadDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
  244. if (payloadDic) {
  245. pushType = [NSString stringWithFormat:@"%@",payloadDic[@"code"]];
  246. pushID = [NSString stringWithFormat:@"%@",payloadDic[@"id"]];
  247. //1 驾考头条推送 2 新闻类型 3 话题相关信息 4 系统信息 5 预约相关 教练列表
  248. if ([pushType integerValue]>=1 && [pushType integerValue]<=6) {
  249. [self gotoPush];
  250. }else{
  251. //其它信息
  252. [self showMsgByArertWithTitle:payloadDic[@"title"] message:payloadDic[@"body"]];
  253. }
  254. }else {
  255. }
  256. }
  257. -(void)showMsgByArertWithTitle:(NSString *)title message:(NSString *)message{
  258. if (message.length == 0) {
  259. return;
  260. }
  261. //其它信息
  262. UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
  263. [alertFind addAction:[UIAlertAction actionWithTitle:@"我知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  264. }]];
  265. [self.window.rootViewController presentViewController:alertFind animated:true completion:nil];
  266. }
  267. #pragma mark 推送相关跳转
  268. - (void)gotoPush {
  269. //1 驾考头条推送 2 新闻类型 3 话题相关信息 4 系统信息 5 预约相关 教练列表
  270. //新闻和驾考头条是一样的
  271. switch ([pushType integerValue]) {
  272. case 1:
  273. [self goToJKTT];
  274. break;
  275. case 2:
  276. [self goToJKTT];
  277. break;
  278. case 3:
  279. [self goToTopic];
  280. break;
  281. case 4:
  282. [self goToSystemNews];
  283. break;
  284. case 5:
  285. [self goToAppoint];
  286. break;
  287. case 6:
  288. [self gotoMyMessage];
  289. break;
  290. default:
  291. [self goToNews];
  292. break;
  293. }
  294. }
  295. - (void)goToJKTT {
  296. }
  297. - (void)goToSystemNews {
  298. }
  299. - (void)goToNews {
  300. }
  301. - (void)goToTopic {
  302. }
  303. - (void)goToAppoint {
  304. }
  305. - (void)gotoMyMessage {
  306. }
  307. #pragma mark - 监测程序状态
  308. //程序复原
  309. - (void)applicationDidBecomeActive:(UIApplication *)application {
  310. //删除程序小红点
  311. [GeTuiSdk resetBadge]; //重置角标计数
  312. [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; // APP 清空角标
  313. if (myDelegate.timer) {
  314. [myDelegate.timer setFireDate:[NSDate distantPast]];
  315. }
  316. myDelegate.isBackgroundTask = NO;
  317. }
  318. @end