iOS远程推送点击消息跳转到指定页面

很多应用都会实现推送功能,我们可以集成第三方框架实现推送功能,
比如:JPush推送:https://www.jpush.cn
个推:http://www.getui.com
下面来说说收到推送消息的逻辑处理
一、收到推送消息有三种情况:
1、应用未启动(默认显示在通知栏,或者锁屏时显示在锁屏页面)
2、应用在后台挂起(默认显示在通知栏,或者锁屏时显示在锁屏页面)
3、应用在前台(默认不显示)
二、点击推送消息有两种情况:1、应用未启动 -> 启动这个时候如论是点击推送消息打开应用还是点击icon打开应用都会调用以下方法(具体的可以根据 userInfo 进行判断):(只有重新打开APP和后台杀死后在打开APP才会走下面的方法)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
 NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
//如果userInfo 有内容说明是点击通知打开的应用,如果没有内容则是点击icon打开的应用
if (userInfo) {
        // 有推送的消息,处理推送的消息         
_isLaunchedByNotification = YES;
      }

}

2、应用在后台 -> 应用在前台应用在后台挂起时点击推送消息和应用在前台时收到推送消息,都会调用以下方法:
ios 7 以上会调用下面这个方法

- (void)application:(UIApplication *)application didReceiveRemoteNotification
:(NSDictionary *)userInfo fetchCompletionHandler:
(void (^)(UIBackgroundFetchResult result))completionHandler{}

ios 10 会调用 下面的方法

// iOS 10 Support(极光) 处于前台的时候 消息推送过来的手机上弹出消息的
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
    // Required
     AudioServicesPlaySystemSound(1007);
    NSDictionary * userInfo = notification.request.content.userInfo;
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
}

// iOS 10 Support(极光) 点击消息的时候才调用的方法
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    // Required
    NSDictionary * userInfo = response.notification.request.content.userInfo;
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    completionHandler();  // 系统要求执行这个方法
}

应用在后台挂起时默认是不调用该方法的,如果你需要接收到推送消息还没点击推送就调用该方法,可以让服务器发给APNS时在aps 字典中加入:
aps = {
content-available = 1;
}

上面对打开APP的方式进行区分和收到通知后所走的方法进行了说明, 下面来说说如何在收到通知后跳转到对应的页面

首先根据APP的状态进行判断 这里当APP在前台显示的时候根据需求我们没有消息进行处理
第一步:发送通知

if (application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground || _isLaunchedByNotification == YES) {
         [self performSelectorOnMainThread:@selector(pushMessageController) withObject:nil waitUntilDone:NO];
    }

//收到消息发送通知 切记一定要在主线程发送通知
- (void)pushMessageController{
    [Center postNotificationName:@"pushMessageController" object:nil];
}

第二步:添加观察者

- (void)viewDidLoad {
//单独处理点击资讯的推送,跳转到资讯的详情页面
    [Center addObserver:self selector:@selector(pushMessageController) name:@"pushMessageController" object:nil];

}

第三步:进行页面的跳转,这地方有一个重点是如何获取的当前页面的然后才能够实现跳转

//通过控制器的布局视图可以获取到控制器实例对象    modal的展现方式需要取到控制器的根视图
- (UIViewController *)currentViewController
{
 UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
// modal展现方式的底层视图不同
// 取到第一层时,取到的是UITransitionView,通过这个view拿不到控制器
UIView *firstView = [keyWindow.subviews firstObject];
UIView *secondView = [firstView.subviews firstObject];
UIViewController *vc = [secondView parentController];

if ([vc isKindOfClass:[UITabBarController class]]) {
    UITabBarController *tab = (UITabBarController *)vc;
    if ([tab.selectedViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController *nav = (UINavigationController *)tab.selectedViewController;
        return [nav.viewControllers lastObject];
    } else {
        return tab.selectedViewController;
    }
} else if ([vc isKindOfClass:[UINavigationController class]]) {
    UINavigationController *nav = (UINavigationController *)vc;
    return [nav.viewControllers lastObject];
} else {
    return vc;
}
return nil;
}

在此给View写了一个分类方法

 - (UIViewController *)parentController
  {
      UIResponder *responder = [self nextResponder];
      while (responder) {
          i f ([responder isKindOfClass:[UIViewController class]]) {
              return (UIViewController *)responder;
          }
          responder = [responder nextResponder];
      }
      return nil;
  }

第四步:实现跳转到目的controller

- (void)pushMessageController{
    NewsDetailsController *vc = [[NewsDetailsController alloc]init];
    vc.hidesBottomBarWhenPushed = YES;
    vc.news_Id = @"";
   
    [[self currentViewController].navigationController pushViewController:vc animated:YES];
}

欢迎更多开发者加qq 556120515 群进来交流

推荐阅读更多精彩内容