编程

当前位置:时时彩平台 > 编程 > iOS初步集成极光推送后你还要做这些事

iOS初步集成极光推送后你还要做这些事

来源:http://www.mrmtshipyard.com 作者:时时彩平台 时间:2019-10-01 14:53

离上次写iOS集成极光推送之后,我还得这样做总结已过去半年了,半年的时间,在码代码的过程中,慢慢的体会到了一点,看到需求、设计不要急于写代码,先在脑子里想想,该怎么设计,应该考虑哪些方面的问题,怎么编写效率更高,用户体验更好等等?这样才能更快的提升。

今天小伙伴问我Badge怎么弄,我这边徽章个数是从服务器请求的,使用WZLBadge这个三方绘制的。另外,我个人遇到的一个崩溃问题 觉得有必要让大家看下。

有关iOS10推送的介绍和使用,早有很多前辈已写好了博客,这里我就不介绍怎么使用推送了,着重介绍本地推送在实际项目中的使用流程,以及需要注意的地方。苹果提供本地推送这么一个功能,我想一般是用来结合网络、时间针对性的提醒某些用户的。

当应用在前台时,接收到通知消息首先会调用极光的这个代理

相比远程推送,1.本地推送没有相关证书方面的要求;2.在没有自己平台推送服务器的情况下,可以在app内部对用户进行推送提醒。而远程推送最大的优点就是可以轻松利用三方平台,无论用户是否有网络,都能随时对app用户进行推送,当然也可以对个别用户进行推送。关键还得看需求~

#pragma mark- JPUSHRegisterDelegate// iOS 10 Support- jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(NSInteger))completionHandler { // Required NSDictionary * userInfo = notification.request.content.userInfo; if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class] ]) { [JPUSHService handleRemoteNotification:userInfo]; } if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) { // 需要执 这个 法,选择 是否提醒 户,有Badge、Sound、Alert三种类型可以选择设置 completionHandler(UNNotificationPresentationOptionSound); }else if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {//后台 // 需要执 这个 法,选择 是否提醒 户,有Badge、Sound、Alert三种类型可以选择设置 completionHandler(UNNotificationPresentationOptionAlert); }else {//未启动 // 需要执 这个 法,选择 是否提醒 户,有Badge、Sound、Alert三种类型可以选择设置 completionHandler(UNNotificationPresentationOptionAlert); }}

图片 1应用处于前台收到通知

在上面代理中有几个判断,当app在前台、后台、未运行。三种状态,解释下Badge:应用角标 Sound:通知声音 Alert:通知栏 如果你同时需要通知栏展示,声音,角标,只需要以|符号连接即可,不需要的直接删除。

谈谈最近公司接的一个项目中的一个需求,以下是项目需求:

如果你在应用内收到通知(非自定义消息,后面会详细说这个),应该在这个 if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {}判断中进行提示、跳转。你可以在这里写一个UIAlertController提示,也可以像我一样提示在顶部,取决你们UI设计。我的代码

用户在使用APP的过程中,要能及时看到他的交易信息,1. 在APP内以弹窗的形式提醒用户,点击“查看”跳转到对应消息界面;2. 在后台运行时,以推送通知的形式提醒用户,用户点击消息跳转到对应的消息界面。由于没有自己的推送服务器,又涉及到网络请求,暂不考虑APP处于退出状态时的情况。
 if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) { /* * 当应用在前台 接到通知 */ NSString *messageAlert = [[userInfo objectForKey:@"aps"]objectForKey:@"alert"]; //获取顶层控制器 UIViewController *currentVC = [self currentViewController]; [TSMessage showNotificationInViewController:currentVC.navigationController title:@"系统通知" subtitle:messageAlert image:[UIImage imageNamed:@"notifi"] type:TSMessageNotificationTypeMessage duration:TSMessageNotificationDurationAutomatic callback:^{ if (currentVC.navigationController) { if ([Person currentLoginUser].userId.length == 11) { //先跳转指定tab然后push到指定页面 BaseTabBarController *myTbabar = (BaseTabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController; myTbabar.selectedIndex = 2; //改变bar后再次获取当前控制器 UIViewController *VC = [self currentViewController]; MyServiceViewController *vc = [[MyServiceViewController alloc] init]; [vc setHidesBottomBarWhenPushed:YES]; [VC.navigationController pushViewController:vc animated:YES]; }else { [SVProgressHUD showInfoWithStatus:@"请登录后,前往我的服务查看。"]; } }else { [SVProgressHUD showErrorWithStatus:@"跳转失败,请自行前往个人中心查看。"]; } } buttonTitle:nil buttonCallback:^{ } atPosition:TSMessageNotificationPositionNavBarOverlay canBeDismissedByUser:YES]; completionHandler(UNNotificationPresentationOptionSound); // 需要执 这个 法,选择 是否提醒 户,有Badge、Sound、Alert三种类型可以选择设置 }

看到这么一个需求,当时就想到用推送,至于远程推还是本地推,当然选择后者,远程推的话必须借助极光推送平台,而且不能满足从公司后台获取用户实时交易的消息,并有针对性的给用户推送。

上面代码我选择了一个提示的第三方TSMessage在点击消息的时候做了一个跳转。在调用这个三方的时候你首先要获取当前顶层控制器赋值给这个三方。 UIViewController *currentVC = [self currentViewController];

下面说说实现思路,涉及到iOS10推送API读取用户对通知权限的设置定时器通知中心界面跳转定时器和通知的移除,以下关于本地通知都用iOS10的API。

//获取Window当前显示的ViewController- (UIViewController*)currentViewController{ //获得当前活动窗口的根视图 UIViewController* vc = [UIApplication sharedApplication].keyWindow.rootViewController; while  { //根据不同的页面切换方式,逐步取得最上层的viewController if ([vc isKindOfClass:[UITabBarController class]]) { vc = ((UITabBarController*)vc).selectedViewController; } if ([vc isKindOfClass:[UINavigationController class]]) { vc = ((UINavigationController*)vc).visibleViewController; } if (vc.presentedViewController) { vc = vc.presentedViewController; }else{ break; } } return vc;}
1.给APP申请通知权限,2.读取用户对通知的设置;3.创建定时器;4.添加通知中心观察者;5.创建 UNUserNotificationCenter对象,配置推送内容;6.分别处理前台和后台接收通知的情况;7.用户点击通知后的界面跳转;8.移除定时器、通知中心对象。

有个细节是,当你跳转指定控制器的时候,你有必要判断当前控制器是否可以push过去,即有没有导航栏,如果没有则不能push,当然也可以像我这样先跳转到个人中心,保证有导航栏,但是这样的处理也许不适用你的app.

开始上代码:

当你在后台,收到消息,通知栏会弹出一个系统alert,一旦你点击了这个alert,目标app会被唤起,同时调用下面代理函数。

  • 1.给APP申请通知权限
// iOS 10 Support- jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:completionHandler;

在这个函数中我们做这样的提示、跳转处理。

 // 1.给APP申请通知权限,关于请求权限务必放在APPdelegate中,程序一启动马上提醒用户选择.否则设置-通知中心根本就没有此应用程序的通知设置,自己想去后台设置打开都找不到地方。 // 这是iOS10请求通知权限的API [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) { // 用户对通知的设置 [[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { DLog(@"%@", settings.authorizationStatus == 2 ? @"成获取到通知权限" : @"用户关闭了通知"); if (settings.authorizationStatus != 2) { DLog(@"用户关闭了通知"); } }]; }];
 // Required NSDictionary *userInfo = response.notification.request.content.userInfo; if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { /* * 应用在后台 点击了通知栏 */ UIViewController *currentVC = [self currentViewController]; if (currentVC.navigationController) { if ([Person currentLoginUser].userId.length == 11) { //先跳转指定tab然后push到指定页面 BaseTabBarController *myTbabar = (BaseTabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController; myTbabar.selectedIndex = 2; MyServiceViewController *vc = [[MyServiceViewController alloc] init]; [vc setHidesBottomBarWhenPushed:YES]; //改变bar后再次获取当前控制器 UIViewController *VC = [self currentViewController]; [VC.navigationController pushViewController:vc animated:YES]; }else { [SVProgressHUD showInfoWithStatus:@"请登录后,前往我的服务查看。"]; } }else { //避免没有导航栏跳转崩溃的问题 [SVProgressHUD showErrorWithStatus:@"跳转失败,请自行前往个人中心查看。"]; } [JPUSHService handleRemoteNotification:userInfo]; } completionHandler(); // 系统要求执 这个 法
  • 2.检查用户对通知功能的设置状态,我放在首页viewDidLoad中,当用户一进入首页如果发现没有打开则以弹窗的形式提醒用户,引导其打开;否则不进行接下来的操作。注:以下代码都放在首页控制器中。

以上跳转代码、获取当前顶层控制器都是相同的,不再解释。

这种情况是最不容易找到的,因为当你的应用未启动,点击了通知栏,它没有调用任何极光的代理,这时候需要我们去启动函数进行判断。

// 2.检查用户对通知功能的设置状态- isPermissionedPushNotification { if ([[UIApplication sharedApplication] currentUserNotificationSettings].types == UIUserNotificationTypeNone) { DLog(@"用户关闭了通知功能"); // 弹窗 UIAlertController *alertvc = [UIAlertController alertControllerWithTitle:@"温馨提醒" message:@"请打开通知功能,否则无法收到交易提醒." preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { DLog(@"引导用户去设置中心打开通知"); // 点击跳转至设置中心 NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; if([[UIApplication sharedApplication] canOpenURL:url]) { NSURL *url =[NSURL URLWithString:UIApplicationOpenSettingsURLString]; [[UIApplication sharedApplication] openURL:url]; } }]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"忽略交易提醒" style:UIAlertActionStyleCancel handler:nil]; [alertvc addAction:cancelAction]; [alertvc addAction:confirmAction]; [self presentViewController:alertvc animated:YES completion:nil]; return false; } else { DLog(@"可以进行推送"); return true; }}
- application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self appStateInactive:launchOptions];}
  • 3.创建定时器,获得新消息未读数
  • 4.创建通知中心观察者

在上面启动函数中调用一个方法,来判断是否是收到通知启动的。最后,进行目标控制器跳转。

- appStateInactive:(NSDictionary *)launchOptions { /* * 当应用不在后台 点击通知栏 */NSDictionary* pushInfo = [launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"];if  { NSDictionary *apsInfo = [pushInfo objectForKey:@"aps"]; if { [self.mainTab.tabBar showBadgeOnItemIndex:2]; UIViewController *currentVC = [self currentViewController]; if (currentVC.navigationController) { if ([Person currentLoginUser].userId.length == 11) { //先跳转指定tab然后push到指定页面 BaseTabBarController *myTbabar = (BaseTabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController; myTbabar.selectedIndex = 2; MyServiceViewController *vc = [[MyServiceViewController alloc] init]; [vc setHidesBottomBarWhenPushed:YES]; //更改后bar后再次获取当前控制器 UIViewController *VC = [self currentViewController]; [VC.navigationController pushViewController:vc animated:YES]; }else { [SVProgressHUD showInfoWithStatus:@"请登录后,前往我的服务查看。"]; } } } } }
- viewDidLoad { [super viewDidLoad]; // ... if ([self isPermissionedPushNotification]) { // 3.创建定时器,获得新消息未读数 self.timer = [NSTimer scheduledTimerWithTimeInterval:RequestTimeInterval target:self selector:@selector(setupUnreadTradeMsg) userInfo:nil repeats:YES]; // 设置timer模式 [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; } // 4.创建通知中心观察者 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(confirmReadNoticeContent:) name:@"ReadNoticeContent" object:nil];}// 定时器执行方法- setupUnreadTradeMsg { dispatch_async(dispatch_get_global_queue, ^{ [NetworkEngine signPostWithURL:PARAMQUERY parmas:params success:^(id requestResult) { // ... // 省略部分网络请求代码 // 设置app角标数量 = 未读消息数量 [[UIApplication sharedApplication] setApplicationIconBadgeNumber:badge]; // 消息按钮红点 [self.msgBtn setBackgroundImage:[UIImage imageNamed:@"new_message"] forState:UIControlStateNormal]; // 将新的交易信息内容传入推送 NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; // ... // 发起推送 [self pushNotificationOfTradeMsg:params]; } failure:^(NSError *error) { // [self showToast:@"请求失败,请检查网络连接"]; return ; }]; });

自定义消息,这个比较特殊,它必须是在app正在前台的时候才能收到消息,收到消息的位置而且不在代理中,而是在一个通知中。

  • 5.配置推送内容

图片 2

当注册极光后可以加入下面代码。注册一个通知。

// 5.配置推送内容- pushNotificationOfTradeMsg:(NSDictionary *)params { // 1、创建通知对象 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; // 必须设置代理,否则无法收到通知 center.delegate = self; // 权限 [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) { if  { // 2、创建通知内容 UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; // 标题 content.title = params[@"title"]; content.body = params[@"content"]; // 声音 content.sound = [UNNotificationSound soundNamed:@"notification.wav"]; // 图片 NSURL *imageUrl = [[NSBundle mainBundle] URLForResource:@"msgImg" withExtension:@"png"]; UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"imageIndetifier" URL:imageUrl options:nil error:nil]; content.attachments = @[attachment]; // 标识符 content.categoryIdentifier = @"categoryIndentifier"; // 3、创建通知触发时间 UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1.0 repeats:NO]; // 4、创建通知请求 UNNotificationRequest *notificationRequest = [UNNotificationRequest requestWithIdentifier:@"KFGroupNotification" content:content trigger:trigger]; // 5、将请求加入通知中心 [center addNotificationRequest:notificationRequest withCompletionHandler:^(NSError * _Nullable error) { if  { DLog(@"已成功加入通知请求"); } else { DLog(@"出错啦%@", [error localizedDescription]); } }]; } }];}
// 注册通知 当收到自定义消息的时候 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil];
  • 6.分别处理前台和后台接收通知的情况

这个通知类型极光文档是这样解释的

kJPFNetworkDidReceiveMessageNotification // 收到消息
/** 6.1当用户处于前台时,消息发送前走这个方法 */-userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(UNNotificationPresentationOptions))completionHandler{ DLog(@"--------通知即将发出-------"); // 在前台时,通过此方法监听到消息发出,不让其在通知栏显示,以弹窗的形式展示出来;设置声音提示 completionHandler(UNNotificationPresentationOptionSound); // 获取消息内容 NSMutableDictionary *content = [[NSMutableDictionary alloc] init]; [content setObject:notification.request.content.title forKey:@"content"]; [content setObject:notification.request.content.body forKey:@"body"]; // 弹窗 UIAlertController *alertvc = [UIAlertController alertControllerWithTitle:notification.request.content.title message:notification.request.content.body preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* updateAction = [UIAlertAction actionWithTitle:@"查看" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // 创建通知对象 NSNotification *notice = [NSNotification notificationWithName:@"ReadNoticeContent" object:nil userInfo:content]; // 发送通知 [[NSNotificationCenter defaultCenter] postNotification:notice]; DLog(@"点击查看消息"); }]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"忽略" style:UIAlertActionStyleCancel handler:nil]; [alertvc addAction:cancelAction]; [alertvc addAction:updateAction]; [self presentViewController:alertvc animated:YES completion:nil];}

/** 6.2不处于前台时,与通知交互走这个方法 */-userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:completionHandler { completionHandler(UIBackgroundFetchResultNewData); // 获取消息内容 NSMutableDictionary *content = [[NSMutableDictionary alloc] init]; [content setObject:response.notification.request.content.title forKey:@"content"]; [content setObject:response.notification.request.content.body forKey:@"body"]; // 判断是否为本地通知 if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { NSLog(@"收到远程通知"); } else { // 判断为本地通知 //创建通知对象 NSNotification *notice = [NSNotification notificationWithName:@"ReadNoticeContent" object:nil userInfo:content]; //发送通知 [[NSNotificationCenter defaultCenter] postNotification:notice]; }}

实现这个通知方法

  • 7.用户点击通知后的界面跳转
/* * 当在前台 接收到 自定义消息 通知 */- networkDidReceiveMessage:(NSNotification *)notification { //有没有未读消息 [self.mainTab.tabBar showBadgeOnItemIndex:2]; NSDictionary *userInfo = [notification userInfo]; NSString *content = [userInfo valueForKey:@"content"]; //获取顶层 UIViewController *currentVC = [self currentViewController]; [TSMessage showNotificationInViewController:currentVC.navigationController title:@"系统通知" subtitle:content image:[UIImage imageNamed:@"notifi"] type:TSMessageNotificationTypeMessage duration:TSMessageNotificationDurationAutomatic callback:^{ //判断是否有导航栏 if (currentVC.navigationController) { if ([Person currentLoginUser].userId.length == 11) { //先跳转指定tab然后push到指定页面 BaseTabBarController *myTbabar = (BaseTabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController; myTbabar.selectedIndex = 2; //改变bar后再次获取当前控制器 UIViewController *VC = [self currentViewController]; MyServiceViewController *vc = [[MyServiceViewController alloc] init]; [vc setHidesBottomBarWhenPushed:YES]; [VC.navigationController pushViewController:vc animated:YES]; }else { [SVProgressHUD showInfoWithStatus:@"请登录后,前往我的服务查看。"]; } }else {//没有导航栏 [SVProgressHUD showErrorWithStatus:@"跳转失败,请自行前往个人中心查看。"]; } } buttonTitle:nil buttonCallback:^{ } atPosition:TSMessageNotificationPositionNavBarOverlay canBeDismissedByUser:YES];}

上面代码几乎和在前台收通知的代码是一样的。有点需要说明的是这里我直接取的content这个key。我这边让后台传的是这个,当然也有后台会放extras这个字段的json数据,我后面会有代码详细说这个解析。

// 点击查看消息,进行界面跳转- confirmReadNoticeContent:(NSDictionary *)content { DLog(@"跳转页面 %@", content); // 点击通知查看内容,角标清零,红点消失 [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; [self.msgBtn setBackgroundImage:[UIImage imageNamed:@"nav_message"] forState:UIControlStateNormal]; // 获取当前跟控制器 UIViewController *rootVC = nil; UIWindow *window = [UIApplication sharedApplication].windows.firstObject; if ([window.rootViewController isKindOfClass:[GFNavigationController class]]) { rootVC = [(GFNavigationController *)window.rootViewController visibleViewController]; } else if ([window.rootViewController isKindOfClass:[GFTabBarController class]]) { GFTabBarController *tabVC = (GFTabBarController *)window.rootViewController; rootVC = [(GFNavigationController *)[tabVC selectedViewController] visibleViewController]; } else { rootVC = window.rootViewController; } // 跳转到消息列表页面 TradeMessageViewController *tmvc = [[TradeMessageViewController alloc] init]; [rootVC.navigationController pushViewController:tmvc animated:YES];}

通知一般不是广播式的,有时候需要针对不同用户群体或者个体发送通知,例如优惠券等。极光提供了几种区分用户的方法,在Web中我们可以看到

  • 8.移除定时器、通知中心对象

图片 3image.png

标签和别名差不多。只说别名。现在有这个场景:我想给我所有的注册用户推送消息,没注册的不想推。这时候,你需要在极光登录成功(非常重要,否则你可能出现注册别名无效的情况)的通知方法中向极光服务器注册Alias。如下代码,建议以userId或者服务器登录返回tag值注册,这样后台方便发送消息。登录成功的通知名称:kJPFNetworkDidLoginNotification

- dealloc { // 移除通知 [[NSNotificationCenter defaultCenter] removeObserver:self]; // 销毁定时器 [self.timer invalidate]; self.timer = nil;}
[JPUSHService setAlias:userId callbackSelector:@selector object:self];

图片 4处于前台时收到消息.gif图片 5处于后台时收到消息.gif

这样你在web选择对应别名发送通知,就可以推送到希望推送到的手机上了。

至此,消息已经可以成功发出,从前台点击查看或从后台点击都可以成功进行界面跳转,然后返回到之前的页面。总结:

在上面我们一直说的都是在控制台直接发送消息,然而实际上我们推送都是后台开发人员以API的形式对接极光的服务器。通知往往携带一些所需的参数,例如红包里面的金额cost...不多说废话,直接看我的解析代码吧!

1、UNUserNotificationCenter对象的创建及内容配置可以根据需要放在控制器中,不一定非得放在APPdelegate中;2、上面前台和后台点击查看消息内容是以发通知的形式进行处理的,其实可以直接用[self methodName]的形式调用,原因是接收通知的方法和点击查看消息的方法在同一个控制器中,如果不在同一个控制器中就得用通知进行接收了。3、这里我的跟控制器是TabBar,所以界面跳转走的是第二个else if,如果是导航控制器或其他,会跟着变的。

//json解析- (NSDictionary *)jsonWithString:(NSString *)dataString { NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; return dic;}//内部收到消息,提示- showMessageWithUserInfo:(NSDictionary *)userInfo { //获取顶层控制器 [self.mainTab.tabBar showBadgeOnItemIndex:2]; UIViewController *currentVC = [self currentViewController]; NSString *messageAlert = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]; NSString *extras = [userInfo objectForKey:@"extras"]; NSDictionary *dic = [self jsonWithString:extras]; NSString *notifiType = [NSString stringWithFormat:@"%@",dic[@"messag_type"]]; [TSMessage showNotificationInViewController:currentVC.navigationController title:@"系统通知" subtitle:messageAlert image:[UIImage imageNamed:@"notifi"] type:TSMessageNotificationTypeMessage duration:TSMessageNotificationDurationAutomatic callback:^{ if (currentVC.navigationController) { if ([Person currentLoginUser].userId.length == 11) { if ([notifiType isEqualToString:@"1"]) {//消息类型 CommentViewController *vc = [[CommentViewController alloc] initWithNibName:@"CommentViewController" bundle:nil]; vc.orderTitle = dic[@"item_title"]; vc.remark = dic[@"comments"]; vc.time = dic[@"item_time"]; vc.orderId = [NSString stringWithFormat:@"%@",dic[@"item_id"]]; [vc setHidesBottomBarWhenPushed:YES]; [currentVC.navigationController pushViewController:vc animated:YES]; }else { //其他消息类型 } }else { [SVProgressHUD showInfoWithStatus:@"请登录后,前往我的服务查看。"]; } }else { [SVProgressHUD showErrorWithStatus:@"跳转失败,请自行前往个人中心查看。"]; } } buttonTitle:nil buttonCallback:^{ } atPosition:TSMessageNotificationPositionNavBarOverlay canBeDismissedByUser:YES]; }//外部收到消息。点击了消息- touchAlertWithUserInfo:(NSDictionary *)userInfo { [self.mainTab.tabBar showBadgeOnItemIndex:2]; UIViewController *currentVC = [self currentViewController]; NSString *extras = userInfo[@"extras"]; NSDictionary *dic = [self jsonWithString:extras]; NSString *notifiType = [NSString stringWithFormat:@"%@",dic[@"messag_type"]]; if (currentVC.navigationController) { if ([Person currentLoginUser].userId.length == 11) { if ([notifiType isEqualToString:@"1"]) {//消息类型 //先跳转指定tab然后push到指定页面 BaseTabBarController *myTbabar = (BaseTabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController; myTbabar.selectedIndex = 1; //改变bar后再次获取当前控制器 UIViewController *VC = [self currentViewController]; CommentViewController *vc = [[CommentViewController alloc] initWithNibName:@"CommentViewController" bundle:nil]; vc.orderTitle = dic[@"item_title"]; vc.remark = dic[@"comments"]; vc.time = dic[@"item_time"]; vc.orderId = [NSString stringWithFormat:@"%@",dic[@"item_id"]]; [vc setHidesBottomBarWhenPushed:YES]; [VC.navigationController pushViewController:vc animated:YES]; } }else { [SVProgressHUD showInfoWithStatus:@"请登录后,前往我的服务查看。"]; } }else { [SVProgressHUD showErrorWithStatus:@"跳转失败,请自行前往个人中心查看。"]; }}

最后,由于是客户的项目,就没有单独整理demo。本地通知实际运用并不难,自己稍微花点时间整理下,就全部弄明白了,思路流程都已经列出来了,可以根据需要一步一步来,这个弄清楚,其实远程通知也差不多了。好了,如果发现有不对或者需要优化的地方,请指出,真心感谢!

我把以上方法独立出来。方法都有注释,不再讲解。那么,这时候我仅仅需要在合适的位置调用这些方法即可!例如。在后台的时候

// iOS 10 Support- jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:completionHandler { // Required NSDictionary *userInfo = response.notification.request.content.userInfo; if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { /* * 应用在后台 点击了通知栏 */ [self touchAlertWithUserInfo:userInfo]; [JPUSHService handleRemoteNotification:userInfo]; } completionHandler(); // 系统要求执 这个 法}

在前台的时候

// iOS 10 Support- jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(NSInteger))completionHandler { // Required NSDictionary *userInfo = notification.request.content.userInfo; if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class] ]) { [JPUSHService handleRemoteNotification:userInfo]; } if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) { /* * 当应用在前台 接到通知 */ NSLog(@"userInfo : %@",userInfo); //提示 [self showMessageWithUserInfo:userInfo]; completionHandler(UNNotificationPresentationOptionSound); // 需要执 这个 法,选择 是否提醒 户,有Badge、Sound、Alert三种类型可以选择设置 }else if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {//后台 completionHandler(UNNotificationPresentationOptionAlert); // 需要执 这个 法,选择 是否提醒 户,有Badge、Sound、Alert三种类型可以选择设置 }else {//未启动 completionHandler(UNNotificationPresentationOptionAlert); // 需要执 这个 法,选择 是否提醒 户,有Badge、Sound、Alert三种类型可以选择设置 }}

我们看到通过方法独立出来,我们的代码更简洁,逻辑也更清晰了。

一般都在app设置中有一个switch的开关。来开启关闭通知,代码很简单,直接贴上来。有一点需要注意,就是这个开关的状态需要存到本地,有高要求的存服务器。

cell.textLabel.text = @"消息提醒"; UISwitch *swi = [[UISwitch alloc] initWithFrame:CGRectMake(CGRectGetWidth(cell.frame)-15,7.5, 45, 30)]; //存储到本地 NSUserDefaults *defaults = [[NSUserDefaults alloc] init]; NSString *isNotification = [defaults objectForKey:@"isNotification"]; NSLog(@"noti %@",isNotification); if ([isNotification isEqualToString:@"0"]) { swi.on = NO; }else { swi.on = YES; } [swi addTarget:self action:@selector forControlEvents:UIControlEventValueChanged]; [cell.contentView addSubview:swi];

#pragma mark -- 消息推送的 开/关- onOrOff:(UISwitch *)swi { NSUserDefaults *defaults = [[NSUserDefaults alloc] init]; if  {//存入本地 [[UIApplication sharedApplication] unregisterForRemoteNotifications];//关闭 [defaults setObject:@"0" forKey:@"isNotification"]; }else { [[UIApplication sharedApplication] registerForRemoteNotifications]; [defaults setObject:@"1" forKey:@"isNotification"]; }}

- application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //是否关闭了推送? NSUserDefaults *defaults = [[NSUserDefaults alloc] init]; NSString *isNotification = [defaults objectForKey:@"isNotification"]; if ([isNotification isEqualToString:@"0"]) { [[UIApplication sharedApplication] unregisterForRemoteNotifications];//关闭 }else { [[UIApplication sharedApplication] registerForRemoteNotifications];//开启 }}

想要测试上架包,首先更改极光注册代码。production改为YES

[JPUSHService setupWithOption:launchOptions appKey:kJPushAPPKey channel:@"apsForProduction" apsForProduction:YES advertisingIdentifier:nil];

(开发、生产证书配置不再说,网上很多)这个就涉及到打包的知识了,开发环境就是真机调试的我就不说了。我们这里使用蒲公英平台安装生产环境包,archive后选择

图片 6image.png

然后选择Ad Hoc

图片 7image.png

这样打包就是生产包了。如果你没有对应的证书可以去配置,同时你还需要配置对应描述文件。iOS技术交流群:511860085 成堆的技术视频福利,欢迎加入!

本文由时时彩平台发布于编程,转载请注明出处:iOS初步集成极光推送后你还要做这些事

关键词:

上一篇:python 正则表达式学习笔记

下一篇:没有了