JPushHelper.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. //
  2. // JPushHelper.m
  3. // SiBenServer
  4. //
  5. // Created by 肖雨 on 2017/8/23.
  6. // Copyright © 2017年 ShangLv. All rights reserved.
  7. //
  8. #import "JPushHelper.h"
  9. @implementation JPushHelper
  10. static JPushHelper *sharedObj = nil;
  11. + (instancetype)sharedInstance
  12. {
  13. static dispatch_once_t onceToken = 0;
  14. dispatch_once(&onceToken, ^{
  15. sharedObj = [[super allocWithZone: NULL] init];
  16. });
  17. return sharedObj;
  18. // static NIMSDKHelper *instance = nil;
  19. // static dispatch_once_t onceToken;
  20. // dispatch_once(&onceToken, ^{
  21. // instance = [[NIMSDKHelper alloc] init];
  22. // });
  23. // return instance;
  24. }
  25. + (id) allocWithZone:(struct _NSZone *)zone
  26. {
  27. return [self sharedInstance];
  28. }
  29. - (id) copyWithZone:(NSZone *) zone
  30. {
  31. return self;
  32. }
  33. - (void)setJPushAPNSSDK:(UIApplication *)application options:(NSDictionary *)launchOptions
  34. {
  35. //打印日志
  36. [JPUSHService setDebugMode];
  37. // APNs注册,获取deviceToken并上报
  38. [self registerAPNS:application];
  39. // 初始化SDK
  40. [self initJPush:launchOptions];
  41. //监听注册推送通道是否成功
  42. [self listenerOnChannelOpened];
  43. }
  44. /**
  45. * 向APNs注册,获取deviceToken用于推送
  46. */
  47. - (void)registerAPNS:(UIApplication *)application
  48. {
  49. JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
  50. entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
  51. //if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {}
  52. [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
  53. }
  54. #pragma mark - SDK 初始化
  55. - (void)initJPush:(NSDictionary *)launchOptions
  56. {
  57. // SDK初始化
  58. [JPUSHService setupWithOption:launchOptions appKey:JPushKey channel:JPushChannel apsForProduction:YES];
  59. // [JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
  60. // NSLog(@"resCode : %d,registrationID: %@",resCode,registrationID);
  61. // }];
  62. //这个是根据手机唯一标识符来推送 我们使用的是别名
  63. // [JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
  64. // if(resCode == 0){
  65. // NSLog(@"registrationID获取成功:%@",registrationID);
  66. // }
  67. // else{
  68. // NSLog(@"registrationID获取失败,code:%d",resCode);
  69. // }
  70. // }];
  71. }
  72. #pragma mark - APNs注册成功回调,将返回的deviceToken上传到JPush服务器
  73. - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  74. //NSLog(@"Upload deviceToken to JPush server.");
  75. [JPUSHService registerDeviceToken:deviceToken];
  76. }
  77. #pragma mark - APNs注册失败回调
  78. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  79. NSLog(@"APNs注册失败: %@", error);
  80. }
  81. #pragma mark - 基于iOS 6 及以下的系统版本,如果 App状态为正在前台或者点击通知栏的通知消息,那么此函数将被调用,并且可通过AppDelegate的applicationState是否为UIApplicationStateActive判断程序是否在前台运行。此种情况在此函数中处理
  82. - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo{
  83. // 通知打开回执上报
  84. [JPUSHService handleRemoteNotification:userInfo];
  85. //app未读消息角标值-1 然后保存到极光服务器 进入此方法 则不会再程序从启的api再对角标值做操作
  86. application.applicationIconBadgeNumber = application.applicationIconBadgeNumber>0?application.applicationIconBadgeNumber-1:0;
  87. //应用正处理前台状态下,并且接收事件,但不会收到推送消息,因此在此处需要额外处理一下 [@"aps"][@"alert"]
  88. if (application.applicationState == UIApplicationStateActive) {
  89. [NewNotifier showNotifer:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]] name:NewPushTitle icon:NewPushImage dismissAfter:NewMessageDisplayTime];
  90. [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) {
  91. [notifier dismiss];
  92. //。。对收到的消息做处理
  93. if (userInfo) {
  94. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  95. [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo];
  96. });
  97. }
  98. }];
  99. return;
  100. }
  101. //应用正处理前台状态下,但不接收事件,通常情况下是点击推送消息唤醒了程序
  102. if (application.applicationState == UIApplicationStateInactive) {
  103. if (userInfo) {
  104. //通过点击推送消息唤醒程序 并且该消息类型需要跳转指定界面
  105. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  106. [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo];
  107. });
  108. }
  109. }
  110. }
  111. #pragma mark - iOS7~iOS9 旧的API处理收到的推送消息通知
  112. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  113. // 通知打开回执上报
  114. [JPUSHService handleRemoteNotification:userInfo];
  115. //app未读消息角标值-1 然后保存到极光服务器 进入此方法 则不会再程序从启的api再对角标值做操作
  116. application.applicationIconBadgeNumber = application.applicationIconBadgeNumber>0?application.applicationIconBadgeNumber-1:0;
  117. //应用正处理前台状态下,并且接收事件,但不会收到推送消息,因此在此处需要额外处理一下 [@"aps"][@"alert"]
  118. if (application.applicationState == UIApplicationStateActive) {
  119. [NewNotifier showNotifer:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]] name:NewPushTitle icon:NewPushImage dismissAfter:NewMessageDisplayTime];
  120. [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) {
  121. [notifier dismiss];
  122. //。。对收到的消息做处理
  123. if (userInfo) {
  124. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  125. [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo];
  126. });
  127. }
  128. }];
  129. return;
  130. }
  131. //应用正处理前台状态下,但不接收事件,通常情况下是点击推送消息唤醒了程序
  132. if (application.applicationState == UIApplicationStateInactive) {
  133. if (userInfo) {
  134. //通过点击推送消息唤醒程序 并且该消息类型需要跳转指定界面
  135. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  136. [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo];
  137. });
  138. }
  139. }
  140. /*
  141. UIBackgroundFetchResultNewData 成功拉取数据
  142. UIBackgroundFetchResultNoData 没有新数据
  143. UIBackgroundFetchResultFailed 拉取数据失败或者超时
  144. */
  145. completionHandler(UIBackgroundFetchResultNewData);
  146. }
  147. /*
  148. #pragma mark - iOS10 前台 API处理收到的通知
  149. - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  150. //NSLog(@"Receive a notification in foregound.");
  151. //收到推送的请求
  152. UNNotificationRequest *request = notification.request;
  153. //收到推送的消息内容
  154. UNNotificationContent *content = request.content;
  155. NSDictionary *userInfo = content.userInfo;
  156. //通知打开回执上报
  157. [JPUSHService handleRemoteNotification:userInfo];
  158. [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber>0?[UIApplication sharedApplication].applicationIconBadgeNumber-1:0;
  159. [NewNotifier showNotifer:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]]];
  160. [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) {
  161. [notifier dismiss];
  162. //对收到的消息做处理
  163. if (userInfo) {
  164. //[[NSNotificationCenter defaultCenter]postNotificationName:MMNotificationMessage object:userInfo userInfo:@{mmNotificationMessageType:mmNotificationMessageUserInfo}];
  165. }
  166. }];
  167. completionHandler(UNNotificationPresentationOptionNone);//通知不弹出
  168. //completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); //需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
  169. }
  170. #pragma mark - iOS10 未启动/后台 API处理收到的通知
  171. - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
  172. NSString *userAction = response.actionIdentifier;
  173. if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) {
  174. //收到推送的请求
  175. UNNotificationRequest *request = response.notification.request;
  176. //收到推送的消息内容
  177. UNNotificationContent *content = request.content;
  178. NSDictionary *userInfo = content.userInfo;
  179. //通知打开回执上报
  180. [JPUSHService handleRemoteNotification:userInfo];
  181. [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber>0?[UIApplication sharedApplication].applicationIconBadgeNumber-1:0;
  182. //对收到的消息做处理
  183. if (userInfo) {
  184. //[[NSNotificationCenter defaultCenter]postNotificationName:MMNotificationMessage object:userInfo userInfo:@{mmNotificationMessageType:mmNotificationMessageUserInfo}];
  185. }
  186. }
  187. completionHandler();
  188. }
  189. */
  190. #pragma mark - 前台 极光SDK对iOS10收到的推送消息做的处理
  191. - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
  192. //收到推送的请求
  193. UNNotificationRequest *request = notification.request;
  194. //收到推送的消息内容
  195. UNNotificationContent *content = request.content;
  196. NSDictionary *userInfo = content.userInfo;
  197. //通知打开回执上报
  198. [JPUSHService handleRemoteNotification:userInfo];
  199. [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber>0?[UIApplication sharedApplication].applicationIconBadgeNumber-1:0;
  200. [NewNotifier showNotifer:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]] name:NewPushTitle icon:NewPushImage dismissAfter:NewMessageDisplayTime];
  201. [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) {
  202. [notifier dismiss];
  203. //对收到的消息做处理
  204. if (userInfo) {
  205. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  206. [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo];
  207. });
  208. }
  209. }];
  210. completionHandler(UNNotificationPresentationOptionNone);//通知不弹出
  211. //completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
  212. }
  213. #pragma mark - 未启动/后台 极光SDK对iOS10收到的推送消息做的处理
  214. - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
  215. NSString *userAction = response.actionIdentifier;
  216. if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) {
  217. //收到推送的请求
  218. UNNotificationRequest *request = response.notification.request;
  219. //收到推送的消息内容
  220. UNNotificationContent *content = request.content;
  221. NSDictionary *userInfo = content.userInfo;
  222. //通知打开回执上报
  223. [JPUSHService handleRemoteNotification:userInfo];
  224. [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber>0?[UIApplication sharedApplication].applicationIconBadgeNumber-1:0;
  225. //对收到的消息做处理
  226. if (userInfo) {
  227. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  228. [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo];
  229. });
  230. }
  231. }
  232. completionHandler(); // 系统要求执行这个方法
  233. }
  234. #pragma mark - 本地推送通知API 处理收到的推送消息通知
  235. - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
  236. {
  237. [[UIApplication sharedApplication] cancelAllLocalNotifications];
  238. application.applicationIconBadgeNumber = application.applicationIconBadgeNumber>0?application.applicationIconBadgeNumber-1:0;
  239. //应用正处理前台状态下,并且接收事件,但不会收到推送消息,因此在此处需要额外处理一下 [@"aps"][@"alert"]
  240. if (application.applicationState == UIApplicationStateActive) {
  241. [NewNotifier showNotifer:notification.alertBody];
  242. [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) {
  243. [notifier dismiss];
  244. //。。对收到的消息做处理
  245. if (notification.userInfo) {
  246. //[[NSNotificationCenter defaultCenter]postNotificationName:MMNotificationMessage object:notification.userInfo userInfo:@{mmNotificationMessageType:mmNotificationMessageUserInfo}];
  247. }
  248. }];
  249. return;
  250. }
  251. //应用正处理前台状态下,但不接收事件,通常情况下是点击推送消息唤醒了程序
  252. if (application.applicationState == UIApplicationStateInactive) {
  253. if (notification.userInfo) {
  254. //通过点击推送消息唤醒程序 并且该消息类型需要跳转指定界面
  255. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  256. //[[NSNotificationCenter defaultCenter]postNotificationName:MMNotificationMessage object:notification.userInfo userInfo:@{mmNotificationMessageType:mmNotificationMessageUserInfo}];
  257. });
  258. }
  259. }
  260. }
  261. #pragma mark - 监听注册推送通道是否成功
  262. /**
  263. * 注册推送通道打开监听
  264. */
  265. - (void)listenerOnChannelOpened {
  266. [[NSNotificationCenter defaultCenter] addObserver:self
  267. selector:@selector(onChannelOpened:)
  268. name:@"CCPDidChannelConnectedSuccess"
  269. object:nil];
  270. }
  271. /**
  272. * 推送通道打开回调
  273. */
  274. - (void)onChannelOpened:(NSNotification *)notification {
  275. NSLog(@"推送消息通道建立成功");
  276. }
  277. #pragma mark - 添加推送对象
  278. - (void)addAlias
  279. {
  280. // [JPUSHService setAlias:[UserEntity sharedInstance].userToken.length>0&&[UserEntity sharedInstance].userToken.length>16?[[UserEntity sharedInstance].userToken substringToIndex:16]:nil completion:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
  281. // NSLog(@"添加推送对象 iResCode:%ld iAlias:%@ seq:%ld", iResCode, iAlias, seq);
  282. // } seq:[[[UserEntity sharedInstance].mobile base64Decode] integerValue]];
  283. }
  284. #pragma mark - 删除推送对象
  285. - (void)deleteAlias
  286. {
  287. //根据极光推送技术支持人员反馈 可以不用删除 因为每次的设置Alias都是覆盖操作
  288. // [JPUSHService deleteAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
  289. // NSLog(@"删除推送对象 iResCode:%ld iAlias:%@ seq:%ld", iResCode, iAlias, seq);
  290. // } seq:[[[UserEntity sharedInstance].mobile base64Decode] integerValue]];
  291. }
  292. #pragma mark - 查询推送对象
  293. - (void)queryAlias
  294. {
  295. // [JPUSHService getAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
  296. // NSLog(@"查询推送对象 iResCode:%ld iAlias:%@ seq:%ld", iResCode, iAlias, seq);
  297. // } seq:[[[UserEntity sharedInstance].mobile base64Decode] integerValue]];
  298. }
  299. - (void)dealloc
  300. {
  301. NSLog(@"推送消息单利类销毁");
  302. [[NSNotificationCenter defaultCenter] removeObserver:self name:@"CCPDidChannelConnectedSuccess" object:nil];
  303. }
  304. @end