APPdelegateModularForPush.m 15 KB

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