AppDelegate+XYPush.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. //
  2. // AppDelegate+XYPush.m
  3. // Starbuds
  4. //
  5. // Created by 翟玉磊 on 2020/6/16.
  6. // Copyright © 2020 翟玉磊. All rights reserved.
  7. //
  8. #import "AppDelegate+XYPush.h"
  9. #import <CloudPushSDK/CloudPushSDK.h>
  10. // iOS 10 notification
  11. #import <UserNotifications/UserNotifications.h>
  12. #import "XYWalletViewController.h"
  13. #import "XYStartAnchorApplyViewController.h"
  14. #import "XYAnchorCenterViewController.h"
  15. #import "XYSetupAnchorApplyInfoViewController.h"
  16. #import "XYAnchorApplyFailureViewController.h"
  17. #import "XYOrderCenterMainViewController.h"
  18. @interface AppDelegate ()<UNUserNotificationCenterDelegate>
  19. @end
  20. @implementation AppDelegate (XYPush)
  21. - (void)push_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  22. // 初始化SDK
  23. [self initCloudPush];
  24. // 监听推送通道打开动作
  25. [self listenerOnChannelOpened];
  26. // 监听推送消息到达
  27. [self registerMessageReceive];
  28. // 点击通知将App从关闭状态启动时,将通知打开回执上报
  29. [CloudPushSDK sendNotificationAck:launchOptions];
  30. // 获取离线推送内容
  31. NSDictionary*dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
  32. if (dictionary) {
  33. // 不为空说明是点击离线推送进入APP的
  34. [self handleNotification:dictionary click:YES];
  35. }
  36. }
  37. /// 推送绑定账号
  38. /// @param callback 回调
  39. - (void)push_bindingAccount:(void(^)(BOOL succes))callback {
  40. [CloudPushSDK bindAccount:[XYUserInfoManager nowUser].userId withCallback:^(CloudPushCallbackResult *res) {
  41. if (res.success) {
  42. NSLog(@"推送绑定账号成功");
  43. } else {
  44. NSLog(@"推送绑定账号失败:%@", res.error);
  45. }
  46. callback(res.success);
  47. }];
  48. }
  49. /// 推送解绑账号
  50. /// @param callback 回调
  51. - (void)push_unbindAccount:(void(^)(BOOL succes))callback {
  52. [CloudPushSDK unbindAccount:^(CloudPushCallbackResult *res) {
  53. if (res.success) {
  54. NSLog(@"推送解绑账号成功");
  55. } else {
  56. NSLog(@"推送解绑账号失败:%@", res.error);
  57. }
  58. callback(res.success);
  59. }];
  60. }
  61. #pragma mark APNs Register
  62. /**
  63. * 向APNs注册,获取deviceToken用于推送
  64. */
  65. - (void)registerAPNS:(UIApplication *)application {
  66. float systemVersionNum = [[[UIDevice currentDevice] systemVersion] floatValue];
  67. if (systemVersionNum >= 10.0) {
  68. // iOS 10 notifications
  69. UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
  70. notificationCenter.delegate = self;
  71. // 请求推送权限
  72. [notificationCenter requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
  73. if (granted) {
  74. // granted
  75. NSLog(@"User authored notification.");
  76. // 向APNs注册,获取deviceToken
  77. dispatch_async(dispatch_get_main_queue(), ^{
  78. [application registerForRemoteNotifications];
  79. });
  80. } else {
  81. // not granted
  82. NSLog(@"User denied notification.");
  83. }
  84. }];
  85. } else if (systemVersionNum >= 8.0) {
  86. // iOS 8 Notifications
  87. #pragma clang diagnostic push
  88. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  89. [application registerUserNotificationSettings:
  90. [UIUserNotificationSettings settingsForTypes:
  91. (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
  92. categories:nil]];
  93. [application registerForRemoteNotifications];
  94. #pragma clang diagnostic pop
  95. } else {
  96. // iOS < 8 Notifications
  97. #pragma clang diagnostic push
  98. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  99. [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
  100. (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
  101. #pragma clang diagnostic pop
  102. }
  103. }
  104. /// 推送注册成功,返回deviceToken
  105. - (void)push_application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  106. [CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *res) {
  107. if (res.success) {
  108. NSLog(@"Register deviceToken success, deviceToken: %@", [CloudPushSDK getApnsDeviceToken]);
  109. // 后台注册设备
  110. [[XYConfigAPIManager new] registerDeviceWithDeviceId:[CloudPushSDK getDeviceId] successHandler:^(ZYLResponseModel *responseModel) {
  111. } failureHandler:^(ZYLNetworkError *error) {
  112. }];
  113. } else {
  114. NSLog(@"Register deviceToken failed, error: %@", res.error);
  115. }
  116. }];
  117. }
  118. #pragma mark SDK Init
  119. - (void)initCloudPush {
  120. // 正式上线建议关闭
  121. #if DEBUG
  122. [CloudPushSDK turnOnDebug];
  123. #endif
  124. // SDK初始化,手动输出appKey和appSecret
  125. [CloudPushSDK asyncInit:self.appConfigModel.channelConfig.pushAppKey appSecret:self.appConfigModel.channelConfig.pushAppSecret callback:^(CloudPushCallbackResult *res) {
  126. if (res.success) {
  127. NSLog(@"Push SDK init success, deviceId: %@.", [CloudPushSDK getDeviceId]);
  128. } else {
  129. NSLog(@"Push SDK init failed, error: %@", res.error);
  130. }
  131. }];
  132. // // SDK初始化,无需输入配置信息
  133. // // 请从控制台下载AliyunEmasServices-Info.plist配置文件,并正确拖入工程
  134. // [CloudPushSDK autoInit:^(CloudPushCallbackResult *res) {
  135. // if (res.success) {
  136. // NSLog(@"Push SDK init success, deviceId: %@.", [CloudPushSDK getDeviceId]);
  137. // } else {
  138. // NSLog(@"Push SDK init failed, error: %@", res.error);
  139. // }
  140. // }];
  141. }
  142. #pragma mark Notification Open
  143. /*
  144. * App处于启动状态时,通知打开回调
  145. */
  146. - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo {
  147. NSLog(@"Receive one notification.");
  148. // 取得APNS通知内容
  149. NSDictionary *aps = [userInfo valueForKey:@"aps"];
  150. // 内容
  151. NSString *content = [aps valueForKey:@"alert"];
  152. // badge数量
  153. NSInteger badge = [[aps valueForKey:@"badge"] integerValue];
  154. // 播放声音
  155. NSString *sound = [aps valueForKey:@"sound"];
  156. // 取得通知自定义字段内容,例:获取key为"Extras"的内容
  157. NSString *Extras = [userInfo valueForKey:@"Extras"]; //服务端中Extras字段,key是自己定义的
  158. NSLog(@"content = [%@], badge = [%ld], sound = [%@], Extras = [%@]", content, (long)badge, sound, Extras);
  159. // iOS badge 清0
  160. application.applicationIconBadgeNumber = 0;
  161. // 同步通知角标数到服务端
  162. [self syncBadgeNum:0];
  163. // 通知打开回执上报
  164. [CloudPushSDK sendNotificationAck:userInfo];
  165. [self handleNotification:userInfo click:NO];
  166. }
  167. #pragma mark — UNUserNotificationCenterDelegate
  168. /**
  169. * App处于前台时收到通知(iOS 10+)
  170. */
  171. - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  172. NSLog(@"Receive a notification in foregound.");
  173. // 处理iOS 10通知,并上报通知打开回执
  174. [self handleiOS10Notification:notification click:NO];
  175. // 通知不弹出
  176. completionHandler(UNNotificationPresentationOptionNone);
  177. // 通知弹出,且带有声音、内容和角标
  178. //completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
  179. }
  180. /**
  181. * 触发通知动作时回调,比如点击、删除通知和点击自定义action(iOS 10+)
  182. */
  183. - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
  184. NSString *userAction = response.actionIdentifier;
  185. // 点击通知打开
  186. if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) {
  187. NSLog(@"User opened the notification.");
  188. // 处理iOS 10通知,并上报通知打开回执
  189. [self handleiOS10Notification:response.notification click:YES];
  190. }
  191. // 通知dismiss,category创建时传入UNNotificationCategoryOptionCustomDismissAction才可以触发
  192. if ([userAction isEqualToString:UNNotificationDismissActionIdentifier]) {
  193. NSLog(@"User dismissed the notification.");
  194. }
  195. completionHandler();
  196. }
  197. /**
  198. * 处理iOS 10通知(iOS 10+)
  199. */
  200. - (void)handleiOS10Notification:(UNNotification *)notification click:(BOOL)click {
  201. UNNotificationRequest *request = notification.request;
  202. UNNotificationContent *content = request.content;
  203. NSDictionary *userInfo = content.userInfo;
  204. // 通知时间
  205. NSDate *noticeDate = notification.date;
  206. // 标题
  207. NSString *title = content.title;
  208. // 副标题
  209. NSString *subtitle = content.subtitle;
  210. // 内容
  211. NSString *body = content.body;
  212. // 角标
  213. int badge = [content.badge intValue];
  214. // 取得通知自定义字段内容,例:获取key为"Extras"的内容
  215. NSString *extras = [userInfo valueForKey:@"Extras"];
  216. // 通知角标数清0
  217. [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
  218. // 同步角标数到服务端
  219. [self syncBadgeNum:0];
  220. // 通知打开回执上报
  221. [CloudPushSDK sendNotificationAck:userInfo];
  222. NSLog(@"Notification, date: %@, title: %@, subtitle: %@, body: %@, badge: %d, extras: %@.", noticeDate, title, subtitle, body, badge, extras);
  223. [self handleNotification:userInfo click:click];
  224. }
  225. /// 处理所有消息
  226. /// @param message 消息体
  227. /// @param click 是否点击通知进来的
  228. - (void)handleNotification:(NSDictionary *)message click:(BOOL)click {
  229. NSLog(@"推送通知消息体:%@", message);
  230. NSInteger actionType = [message[@"actionType"] integerValue];
  231. if (!click) {
  232. // 不是点击通知进来的不需要进行跳转处理
  233. return;
  234. }
  235. if (actionType == 101) {
  236. // 跳转h5
  237. NSString *h5Url = message[@"h5Url"];
  238. if (StringIsNotEmpty(h5Url)) {
  239. if (ApplicationDelegate.tabbarVC) {
  240. BaseWebViewController *controller = BaseWebViewController.new;
  241. controller.requestUrl = h5Url;
  242. [[self getCurrentController].navigationController pushViewController:controller animated:YES];
  243. }
  244. }
  245. }else if (actionType == 201) {
  246. // 跳转本地
  247. NSString *moduleType = message[@"moduleType"];
  248. NSString *moduleId = message[@"moduleId"];
  249. if (ApplicationDelegate.tabbarVC == nil) {
  250. // 没有tabbar控制器 没有主控制器
  251. return;
  252. }
  253. if ([moduleType isEqualToString:@"liveRoom"]) {
  254. // 直播间 moduleId: 主播id
  255. if (StringIsNotEmpty(moduleId)) {
  256. [[XYLiveManger shareInstance] pushLiveRoom:moduleId extra:nil];
  257. }
  258. }else if ([moduleType isEqualToString:@"profile"]) {
  259. // 个人主页 moduleId: 用户id
  260. if (StringIsNotEmpty(moduleId)) {
  261. XYUserMainViewController *controller = XYUserMainViewController.new;
  262. controller.targetId = moduleId;
  263. [[self getCurrentController].navigationController pushViewController:controller animated:YES];
  264. }
  265. }else if ([moduleType isEqualToString:@"wallet"]) {
  266. // 钱包 moduleId: 用户id
  267. if (StringIsNotEmpty(moduleId)) {
  268. XYWalletViewController *controller = XYWalletViewController.new;
  269. [[self getCurrentController].navigationController pushViewController:controller animated:YES];
  270. }
  271. }else if ([moduleType isEqualToString:@"anchor"]) {
  272. // 主播中心 moduleId: 用户id
  273. [[XYUserInfoManager new] updataUserInfoSuccess:^(BOOL isSuccess) {
  274. /// 认证状态 0:待认证 1:通过 2:未通过 -1:未提交
  275. if ([XYUserInfoManager nowUser].applyStatus == -1) {
  276. [[self getCurrentController].navigationController pushViewController:XYStartAnchorApplyViewController.new animated:YES];
  277. }else if ([XYUserInfoManager nowUser].applyStatus == 0) {
  278. [[self getCurrentController].navigationController pushViewController:XYSetupAnchorApplyInfoViewController.new animated:YES];
  279. }else if ([XYUserInfoManager nowUser].applyStatus == 2) {
  280. [[self getCurrentController].navigationController pushViewController:XYAnchorApplyFailureViewController.new animated:YES];
  281. }else if ([XYUserInfoManager nowUser].applyStatus == 1) {
  282. [[self getCurrentController].navigationController pushViewController:XYAnchorCenterViewController.new animated:YES];
  283. }
  284. }];
  285. }
  286. }else if (actionType == 501) {
  287. if (ApplicationDelegate.tabbarVC == nil) {
  288. // 没有tabbar控制器 没有主控制器
  289. return;
  290. }
  291. // 跳转到技能订单中心
  292. [[self getCurrentController].navigationController pushViewController:XYOrderCenterMainViewController.new animated:YES];
  293. }
  294. }
  295. #pragma mark Channel Opened
  296. /**
  297. * 注册推送通道打开监听
  298. */
  299. - (void)listenerOnChannelOpened {
  300. [[NSNotificationCenter defaultCenter] addObserver:self
  301. selector:@selector(onChannelOpened:)
  302. name:@"CCPDidChannelConnectedSuccess"
  303. object:nil];
  304. }
  305. /**
  306. * 推送通道打开回调
  307. */
  308. - (void)onChannelOpened:(NSNotification *)notification {
  309. NSLog(@"消息通道建立成功");
  310. }
  311. #pragma mark Receive Message
  312. /**
  313. * @brief 注册推送消息到来监听
  314. */
  315. - (void)registerMessageReceive {
  316. [[NSNotificationCenter defaultCenter] addObserver:self
  317. selector:@selector(onMessageReceived:)
  318. name:@"CCPDidReceiveMessageNotification"
  319. object:nil];
  320. }
  321. /**
  322. * 处理到来推送消息
  323. */
  324. - (void)onMessageReceived:(NSNotification *)notification {
  325. NSLog(@"Receive one message!");
  326. CCPSysMessage *message = [notification object];
  327. NSString *title = [[NSString alloc] initWithData:message.title encoding:NSUTF8StringEncoding];
  328. NSString *body = [[NSString alloc] initWithData:message.body encoding:NSUTF8StringEncoding];
  329. NSLog(@"Receive message title: %@, content: %@.", title, body);
  330. }
  331. /* 同步通知角标数到服务端 */
  332. - (void)syncBadgeNum:(NSUInteger)badgeNum {
  333. [CloudPushSDK syncBadgeNum:badgeNum withCallback:^(CloudPushCallbackResult *res) {
  334. if (res.success) {
  335. NSLog(@"Sync badge num: [%lu] success.", (unsigned long)badgeNum);
  336. } else {
  337. NSLog(@"Sync badge num: [%lu] failed, error: %@", (unsigned long)badgeNum, res.error);
  338. }
  339. }];
  340. }
  341. @end