今天恰好有个需求当点击推送需要跳转到指定控制器,找了很多资料,自己也想了很久没有一个极佳的办法,再经过多番试炼之后,终于找到一个不错的方法,接下来先从集成友盟推送开始:
此文章分为两部分:
1.集成友盟推送
2.点击推送跳转到指定控制器
1.1 开始:如果你没有创建应用,那么首先去创建应用吧
获得 AppKey 和 AppSecret (后面用)
1.2 接着: 到iOS集成友盟推送SDK文档中心:http://dev.umeng.com/push/ios/integration下载UMessage_Sdk_All_x.x.x.zip压缩包并解压缩
下载的压缩包中将包括以下内容:
文件名称介绍
UMessage_Sdk_Introductions.html该文件介绍如何使用【友盟+】消息推送SDK
UMessage_Sdk_ReleaseNotes.html该文件记录了【友盟+】消息推送SDK的更新日志
UMessage_Sdk_Api_Reference/该文件夹中包含了【友盟+】消息推送的API文档
UMessage_Sdk_x.x.x/该文件夹中包含了SDK的库文件
UMessage_Sdk_Demo/该文件夹中包含了示例工程
NotificatonService/iOS10的Notificaton Service
1.3 将SDK 文件拖入或者拷贝到你项目中
拖入会弹出这个窗:
拷贝:
右键添加到指定的文件夹中
3.1 引入库文件
增加UserNotifications.framework到项目中。
具体操作如下:点击项目---->TARGET---->Build Phases---->Link Binary with Libraries---->左侧+号---->搜索UserNotifications---->选中UserNotifications.framework---->点击Add
3.2 打开推送开关
点击项目---->TARGET---->Capabilities,将这里的Push Notification的开关打开
1.4 集成推送
4.1 好,前面都是准备工作,现在上代码:
进入 AppDelegate.m
引入 UMessage.h,UserNotifications.h
在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中:
UMConfigInstance.appKey = @"AppKey";
UMConfigInstance.channelId = @"App Store";
[MobClick startWithConfigure:UMConfigInstance];
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
[MobClick setAppVersion:version];
//打开日志,方便测试
[MobClick setLogEnabled:NO];
// 适配Https
[UMessage startWithAppkey:@"AppKey" launchOptions:launchOptions httpsEnable:YES];
//注册通知
[UMessage registerForRemoteNotifications];
//ios10针对
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
UNAuthorizationOptions types10 = UNAuthorizationOptionBadge | UNAuthorizationOptionAlert|UNAuthorizationOptionSound;
[center requestAuthorizationWithOptions:types10 completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted){ //点击允许
NSLog(@"点击允许了");
}else{ //点击不允许
NSLog(@"点击不允许");
}
}];
//测试日志
[UMessage setLogEnabled:NO];
4.2 接收通知
//iOS10以下使用这个方法接收通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo {
// 关闭自动推送
[UMessage setAutoAlert:NO];
//统计点击数
[UMessage didReceiveRemoteNotification:userInfo];
if ([userInfo[@"type"] isEqualToString:@"workflow"]){
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifyPresnetWeb" object:userInfo];
}
}
//iOS10新增:处理前台收到通知的代理方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
NSDictionary *userInfo = notification.request.content.userInfo;
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//应用处于前台的远程推送接受
//关闭友盟自带的alert
[UMessage setAutoAlert:NO];
//必须加这句代码
[UMessage didReceiveRemoteNotification:userInfo];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%@",userInfo[@"aps"][@"alert"]] message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"查看", nil];
_notification = userInfo;
alert.delegate = self;
[alert show];
}else {
//应用处于前台时的本地推送接受
NSLog(@"大帅处于前台的本地的消息来了%@",[NSString stringWithFormat:@"%@",userInfo]);
}
//当应用处于前台时提示设置,需要哪个可以设置哪一个
completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);
}
这句代码不写,会报一个 completionHandler never called 错误信息
completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);
//iOS10新增:处理后台点击通知的代理方法
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//应用处于后台时的远程推送接受
[UMessage didReceiveRemoteNotification:userInfo];
NSLog(@"大帅的远程推送的消息来了%@",userInfo);
if ([userInfo[@"type"] isEqualToString:@"workflow"]){
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifyPresnetNotice" object:userInfo];
}
}else{
//应用处于后台时的本地推送接受
NSLog(@"小帅的本地后台推送的消息来了%@",userInfo);
}
}
2.跳转指定控制器部分
2.1 还是在 delegate.m中
// 弹窗监听方法
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(@"点击取消");
}else{
if ([_notification[@"type"] isEqualToString:@"workflow"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifyPresnetNotice" object:_notification];
}
[alertView dismissWithClickedButtonIndex:buttonIndex animated:YES];
NSLog(@"点击确定按钮");
}
}
2.2 在 tabBarVC.m 中接收通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(presentNotice:) name:@"notifyPresnetNotice" object:nil];
2.3 这里要借用到一个工具类
得益于http://www.jianshu.com/p/bc3c80fa5166 的作者写的工具类, 里面写的挺详细,但我根据自己实际情况汲取了一些代码
工具类在作者的GitHub: https://github.com/liu521227/PushDemo 中,可自己下载
下载后只需将工具拖入或拷贝到项目中就可以
在 tabBarVC.m 中导入头文件 #import "NSObject+Tool.h"
这时候实现你的通知方法:
// MARK: - 跳转到公告页面
- (void)presentNotice:(NSNotification *)info {
IAAnnouncementVC *announceVC = [[IAAnnouncementVC alloc]init]; // 创建你的目标控制器
announceVC.hidesBottomBarWhenPushed = YES; // 隐藏你的 tabBar
// [self currentViewController] 调用工具类的 - currentViewController 方法 获取当前控制器
会打印两次,第一次是当前控制器, 第二次是目标控制器
if (![[self currentViewController] isKindOfClass:[IAAnnouncementVC class]]) { // 这个判断防止两次执行里面代码
// 如果不想隐藏导航栏返回按钮文字就去掉这个判断
if (![[self currentViewController] isKindOfClass:[IAMessageVC class]]) {// 如果不是父控制器就进入,应领导要求,不是从父控制器(指的是正常进入目标控制器的父控制器) 就隐藏导航栏返回按钮的文字
// 隐藏导航栏返回按钮的文字
[self currentViewController].navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:self action:nil];
}else { // 这个判断是走完上面方法之后,所有返回按钮文字都隐藏了, 下面这方法可以解决这个问题
[self currentViewController].navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[self currentViewController].title style:UIBarButtonItemStylePlain target:self action:nil];
}
// 正角来了,这个方法可以让你在任何页面都可以跳转到目标控制器, 当然返回也是进入之前的页面(爱奇艺也是这效果)
[[self currentViewController].navigationController pushViewController:announceVC animated:YES];
}
}