// // JPushHelper.m // SiBenServer // // Created by 肖雨 on 2017/8/23. // Copyright © 2017年 ShangLv. All rights reserved. // #import "JPushHelper.h" @implementation JPushHelper static JPushHelper *sharedObj = nil; + (instancetype)sharedInstance { static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ sharedObj = [[super allocWithZone: NULL] init]; }); return sharedObj; // static NIMSDKHelper *instance = nil; // static dispatch_once_t onceToken; // dispatch_once(&onceToken, ^{ // instance = [[NIMSDKHelper alloc] init]; // }); // return instance; } + (id) allocWithZone:(struct _NSZone *)zone { return [self sharedInstance]; } - (id) copyWithZone:(NSZone *) zone { return self; } - (void)setJPushAPNSSDK:(UIApplication *)application options:(NSDictionary *)launchOptions { //打印日志 [JPUSHService setDebugMode]; // APNs注册,获取deviceToken并上报 [self registerAPNS:application]; // 初始化SDK [self initJPush:launchOptions]; //监听注册推送通道是否成功 [self listenerOnChannelOpened]; } /** * 向APNs注册,获取deviceToken用于推送 */ - (void)registerAPNS:(UIApplication *)application { JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init]; entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound; //if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {} [JPUSHService registerForRemoteNotificationConfig:entity delegate:self]; } #pragma mark - SDK 初始化 - (void)initJPush:(NSDictionary *)launchOptions { // SDK初始化 [JPUSHService setupWithOption:launchOptions appKey:JPushKey channel:JPushChannel apsForProduction:YES]; // [JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) { // NSLog(@"resCode : %d,registrationID: %@",resCode,registrationID); // }]; //这个是根据手机唯一标识符来推送 我们使用的是别名 // [JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) { // if(resCode == 0){ // NSLog(@"registrationID获取成功:%@",registrationID); // } // else{ // NSLog(@"registrationID获取失败,code:%d",resCode); // } // }]; } #pragma mark - APNs注册成功回调,将返回的deviceToken上传到JPush服务器 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { //NSLog(@"Upload deviceToken to JPush server."); [JPUSHService registerDeviceToken:deviceToken]; } #pragma mark - APNs注册失败回调 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"APNs注册失败: %@", error); } #pragma mark - 基于iOS 6 及以下的系统版本,如果 App状态为正在前台或者点击通知栏的通知消息,那么此函数将被调用,并且可通过AppDelegate的applicationState是否为UIApplicationStateActive判断程序是否在前台运行。此种情况在此函数中处理 - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo{ // 通知打开回执上报 [JPUSHService handleRemoteNotification:userInfo]; //app未读消息角标值-1 然后保存到极光服务器 进入此方法 则不会再程序从启的api再对角标值做操作 application.applicationIconBadgeNumber = application.applicationIconBadgeNumber>0?application.applicationIconBadgeNumber-1:0; //应用正处理前台状态下,并且接收事件,但不会收到推送消息,因此在此处需要额外处理一下 [@"aps"][@"alert"] if (application.applicationState == UIApplicationStateActive) { [NewNotifier showNotifer:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]] name:NewPushTitle icon:NewPushImage dismissAfter:NewMessageDisplayTime]; [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) { [notifier dismiss]; //。。对收到的消息做处理 if (userInfo) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo]; }); } }]; return; } //应用正处理前台状态下,但不接收事件,通常情况下是点击推送消息唤醒了程序 if (application.applicationState == UIApplicationStateInactive) { if (userInfo) { //通过点击推送消息唤醒程序 并且该消息类型需要跳转指定界面 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo]; }); } } } #pragma mark - iOS7~iOS9 旧的API处理收到的推送消息通知 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // 通知打开回执上报 [JPUSHService handleRemoteNotification:userInfo]; //app未读消息角标值-1 然后保存到极光服务器 进入此方法 则不会再程序从启的api再对角标值做操作 application.applicationIconBadgeNumber = application.applicationIconBadgeNumber>0?application.applicationIconBadgeNumber-1:0; //应用正处理前台状态下,并且接收事件,但不会收到推送消息,因此在此处需要额外处理一下 [@"aps"][@"alert"] if (application.applicationState == UIApplicationStateActive) { [NewNotifier showNotifer:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]] name:NewPushTitle icon:NewPushImage dismissAfter:NewMessageDisplayTime]; [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) { [notifier dismiss]; //。。对收到的消息做处理 if (userInfo) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo]; }); } }]; return; } //应用正处理前台状态下,但不接收事件,通常情况下是点击推送消息唤醒了程序 if (application.applicationState == UIApplicationStateInactive) { if (userInfo) { //通过点击推送消息唤醒程序 并且该消息类型需要跳转指定界面 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo]; }); } } /* UIBackgroundFetchResultNewData 成功拉取数据 UIBackgroundFetchResultNoData 没有新数据 UIBackgroundFetchResultFailed 拉取数据失败或者超时 */ completionHandler(UIBackgroundFetchResultNewData); } /* #pragma mark - iOS10 前台 API处理收到的通知 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { //NSLog(@"Receive a notification in foregound."); //收到推送的请求 UNNotificationRequest *request = notification.request; //收到推送的消息内容 UNNotificationContent *content = request.content; NSDictionary *userInfo = content.userInfo; //通知打开回执上报 [JPUSHService handleRemoteNotification:userInfo]; [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber>0?[UIApplication sharedApplication].applicationIconBadgeNumber-1:0; [NewNotifier showNotifer:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]]]; [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) { [notifier dismiss]; //对收到的消息做处理 if (userInfo) { //[[NSNotificationCenter defaultCenter]postNotificationName:MMNotificationMessage object:userInfo userInfo:@{mmNotificationMessageType:mmNotificationMessageUserInfo}]; } }]; completionHandler(UNNotificationPresentationOptionNone);//通知不弹出 //completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); //需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置 } #pragma mark - iOS10 未启动/后台 API处理收到的通知 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { NSString *userAction = response.actionIdentifier; if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) { //收到推送的请求 UNNotificationRequest *request = response.notification.request; //收到推送的消息内容 UNNotificationContent *content = request.content; NSDictionary *userInfo = content.userInfo; //通知打开回执上报 [JPUSHService handleRemoteNotification:userInfo]; [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber>0?[UIApplication sharedApplication].applicationIconBadgeNumber-1:0; //对收到的消息做处理 if (userInfo) { //[[NSNotificationCenter defaultCenter]postNotificationName:MMNotificationMessage object:userInfo userInfo:@{mmNotificationMessageType:mmNotificationMessageUserInfo}]; } } completionHandler(); } */ #pragma mark - 前台 极光SDK对iOS10收到的推送消息做的处理 - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler { //收到推送的请求 UNNotificationRequest *request = notification.request; //收到推送的消息内容 UNNotificationContent *content = request.content; NSDictionary *userInfo = content.userInfo; //通知打开回执上报 [JPUSHService handleRemoteNotification:userInfo]; [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber>0?[UIApplication sharedApplication].applicationIconBadgeNumber-1:0; [NewNotifier showNotifer:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]] name:NewPushTitle icon:NewPushImage dismissAfter:NewMessageDisplayTime]; [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) { [notifier dismiss]; //对收到的消息做处理 if (userInfo) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo]; }); } }]; completionHandler(UNNotificationPresentationOptionNone);//通知不弹出 //completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置 } #pragma mark - 未启动/后台 极光SDK对iOS10收到的推送消息做的处理 - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { NSString *userAction = response.actionIdentifier; if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) { //收到推送的请求 UNNotificationRequest *request = response.notification.request; //收到推送的消息内容 UNNotificationContent *content = request.content; NSDictionary *userInfo = content.userInfo; //通知打开回执上报 [JPUSHService handleRemoteNotification:userInfo]; [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber>0?[UIApplication sharedApplication].applicationIconBadgeNumber-1:0; //对收到的消息做处理 if (userInfo) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:NewJitaoServerPublicNotification object:userInfo]; }); } } completionHandler(); // 系统要求执行这个方法 } #pragma mark - 本地推送通知API 处理收到的推送消息通知 - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { [[UIApplication sharedApplication] cancelAllLocalNotifications]; application.applicationIconBadgeNumber = application.applicationIconBadgeNumber>0?application.applicationIconBadgeNumber-1:0; //应用正处理前台状态下,并且接收事件,但不会收到推送消息,因此在此处需要额外处理一下 [@"aps"][@"alert"] if (application.applicationState == UIApplicationStateActive) { [NewNotifier showNotifer:notification.alertBody]; [NewNotifier handleClickAction:^(NSString *name,NSString *detail, NewNotifier *notifier) { [notifier dismiss]; //。。对收到的消息做处理 if (notification.userInfo) { //[[NSNotificationCenter defaultCenter]postNotificationName:MMNotificationMessage object:notification.userInfo userInfo:@{mmNotificationMessageType:mmNotificationMessageUserInfo}]; } }]; return; } //应用正处理前台状态下,但不接收事件,通常情况下是点击推送消息唤醒了程序 if (application.applicationState == UIApplicationStateInactive) { if (notification.userInfo) { //通过点击推送消息唤醒程序 并且该消息类型需要跳转指定界面 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //[[NSNotificationCenter defaultCenter]postNotificationName:MMNotificationMessage object:notification.userInfo userInfo:@{mmNotificationMessageType:mmNotificationMessageUserInfo}]; }); } } } #pragma mark - 监听注册推送通道是否成功 /** * 注册推送通道打开监听 */ - (void)listenerOnChannelOpened { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChannelOpened:) name:@"CCPDidChannelConnectedSuccess" object:nil]; } /** * 推送通道打开回调 */ - (void)onChannelOpened:(NSNotification *)notification { NSLog(@"推送消息通道建立成功"); } #pragma mark - 添加推送对象 - (void)addAlias { // [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) { // NSLog(@"添加推送对象 iResCode:%ld iAlias:%@ seq:%ld", iResCode, iAlias, seq); // } seq:[[[UserEntity sharedInstance].mobile base64Decode] integerValue]]; } #pragma mark - 删除推送对象 - (void)deleteAlias { //根据极光推送技术支持人员反馈 可以不用删除 因为每次的设置Alias都是覆盖操作 // [JPUSHService deleteAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) { // NSLog(@"删除推送对象 iResCode:%ld iAlias:%@ seq:%ld", iResCode, iAlias, seq); // } seq:[[[UserEntity sharedInstance].mobile base64Decode] integerValue]]; } #pragma mark - 查询推送对象 - (void)queryAlias { // [JPUSHService getAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) { // NSLog(@"查询推送对象 iResCode:%ld iAlias:%@ seq:%ld", iResCode, iAlias, seq); // } seq:[[[UserEntity sharedInstance].mobile base64Decode] integerValue]]; } - (void)dealloc { NSLog(@"推送消息单利类销毁"); [[NSNotificationCenter defaultCenter] removeObserver:self name:@"CCPDidChannelConnectedSuccess" object:nil]; } @end