最近的项目中使用了推送模块,使用的是企鹅帝国的信鸽推送服务,关于具体怎么推送的,证书如何设置,我不再赘述,一来开发文档中已经讲的非常清楚,二来在网上一搜的话也能搜到一大堆;在这里主要写下关于推送的通知来了之后点击此通知该如何处理,也是对自己做完之后做一个笔记

在这里我项目中所要达到的效果是点击通知栏的推送消息,就进入应用中的相应页;默认的效果是点击推送消息,会直接进入应用,如果应用未启动,则会启动应用进入首页如果应用已启动,只是点击home退入后台的话,则会返回应用,并且应用之前在哪一个界面,依然是那个界面;

1.如果是应用未启动

则可以通过

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions

方法来判断是点击图标启动应用还是点击推送消息启动应用,如果是点击推送启动应用的话,上面的那个方法的launchOptions必不为nil,可以通过是否为nil进行判断;然后可以通过

    if(launchOptions) {

    NSDictionary* remoteNotification = [launchOptionsobjectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

    if(remoteNotification) {

    NSLog(@"推送过来的消息是%@",remoteNotification);

    //点击推送通知进入指定界面(这个肯定是相当于从后台进入的)

    [self goToMssageViewControllerWith:remoteNotification];//进入相应页面的方法

    }

    }

返回的词典remoteNotification就是推送的消息主体,可以在此进行打印查看,然后判断是点击推送消息启动的应用之后,在goToMssageViewControllerWith:的方法里面写进入自己消息对应页面的代码(下面再讲)

2.如果应用已启动,挂在后台

这种情况下点击推送的消息进入应用时会调用

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo

userInfo就是推送的消息的主体

在这个方法中可以进行自己进入消息对应页面的代码操作

3.如果推送消息到达时应用就在前台运行

这种情况依然会调用2.中的方法,但是如果你什么都没设置,用户就不会知道你推送了消息,如果你设置了进入对应页面,则应用会一下子很突然的进入对应界面,体验不好;这个时候就需要判断应用是在前台运行还是挂在后台(如果程序未启动就不用考虑这种情况)

    if([UIApplicationsharedApplication].applicationState==UIApplicationStateActive)

    {//前台运行时,收到推送的通知会弹出alertview提醒

    NSDictionary*oneDict = [userInfoobjectForKey:@"aps"];

    NSDictionary*twoDict = [oneDictobjectForKey:@"alert"];

    NSString*msg = [twoDictobjectForKey:@"body"];

    UIAlertView*alert = [[UIAlertViewalloc]initWithTitle:@"温馨提 示"message:msgdelegate:selfcancelButtonTitle:nilotherButtonTitles:@"确 定",nil];

    [alertshow];

    }

    else if ([UIApplicationsharedApplication].applicationState==UIApplicationStateInactive)

    {//点击推送通知进入界面的时候

    [self goToMssageViewControllerWith:userInfo];

    }

UIApplicationsharedApplication].applicationState有三个状态,分别是UIApplicationStateActive//应用正在前台运行

UIApplicationStateInactive//点击推送的通知进入应用

UIApplicationStateBackground//应用在后台挂起

这里面只须判断应用是在前台运行(2.)还是点击推送通知进入应用(3.)了, 然后再进行相应的处理,我项目中所用的是如果在前台运行,推送消息来了就弹窗告知,不过感觉不是很好,读者可用自己方法,也可以用第三方 MBProgressHUD中的那个浮现两三秒自动消失的控件来操作;如果是点击推送通知进入应用,我还是用的那个进入相应界面的方法

4.如何进入推送消息相应的界面

重头戏来了额,做到这块的时候我在网上搜了好多,但并没什么很多值得参考的资料,最后的话在cocoaChina论坛中找到一个值得参考的http://www.cocoachina.com/bbs/read.php?tid=257582,里面的8楼说的很有道理,我也是基于此做的;

首先关于推送的消息这 块,比如你推送的消息分为三类,一类是点击消息进入A页面,一类是点击进入B页面,一类是点击进入C页面,你可以在推送的消息主体中设置一个事件值 EventID,定义101就是关于A页面的消息,102就是关于B页面的消息,103就是关于C页面的消息;然后接收到消息主体后解析出来进行判断,可 以使用switch case进行判断,

    NSIntegerEventID = [[msgDic objectForKey:@"eventId"]integerValue];

    switch(EventID) {

    case101: {//写进入A页面的代码

    break;

    }

    case102: {//写进入B页面的代码

    break;

    }

    case103: {//写进入C页面的代码

    break;

    }

    default:

    break;

    }

然后是进入相应的界面,我这里做的处理是已知消息对应的界面之后,在appdelegate文件中包含此界面的头文件,然后在对应的位置处进行初始化,然后present过去

    case101: {

    //进入A界面

    AViewController *Avc = [[AViewController alloc] init];

    [self.window.rootViewController  presentViewController:Avc animated:YES  completion: nil ]; 

    break;

    }

这里的话要说明几点

第一、以上代码是只是针对与不带导航栏的简单页面,并且A页面与其上级界面并没有数据传递,也就是说,A页面的初始化并没有用到它上一级页面的数据

第二、很明显,大家想要进入的页面没有像A这么简单的;就像我这次,有一类是进入带有导航栏的页面;有一类是进入tabbar的其中一个标签页面

A.如何进入带有导航栏的页面

对于这个我问题我也只找了好久,试探了好几种办法,比如使用根视图的导航控制器进行push,均不行,最后使用的就是之前参考那个论坛上的方法;

    case101: {

    //进入带有导航栏的A页面

    AViewController*Avc = [[AViewControlleralloc]init];

    UINavigationController*planNav = [[UINavigationControlleralloc]initWithRootViewController:Avc];

    [self.window.rootViewController presentViewController:planNav animated:YES  completion: nil ];

    break;

    }

使用把A页面装入导航控制器中,然后present导航控制器就好了,这样点击推送消息就可以进入带有导航控制器的页面了;如果A页面是从上个界面push过来的,并且初始化的时候使用到了上级界面的一些数据,这种情况的话,就需要让推送消息把这些数据一并推送过来,然后进行解析,在上面进行初始化的时候使用这些数据进行初始化,相当于断绝它与上级界面的关系;剩下的还有一点就是导航栏上的返回键了,因为是present过去的,所以系统导航栏自带的backBarButtonItem并不会出现,即使你在那个present方法最后一个block参数中设置也不行;这里的话用的是之前说的那个论坛哥们说的方法,在viewwillappear方法里面进行判断

    - (void)viewWillAppear:(BOOL)animated {

    //判断是否是点击推送过来的,如果是的话设置左导航标签为返回键

    NSUserDefaults*pushJudge = [NSUserDefaultsstandardUserDefaults];

    if([[pushJudgeobjectForKey:@"push"]isEqualToString:@"push"]) {

    //给导航栏加一个返回按钮,便于将推送进入的页面返回出去,如果不是推送进入该页面,那肯定是通过导航栏进入的,则页面导航栏肯定会有导航栏自带的leftBarButtonItem返回上一个页面

    UIBarButtonItem*leftButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReplytarget:self action:@selector(rebackToRootViewAction)];

    self.navigationItem.leftBarButtonItem= leftButton;

    }else{

    self.navigationItem.leftBarButtonItem=nil;

    }

    }
    - (void)rebackToRootViewAction {

    //将标示条件置空,以防通过正常情况下导航栏进入该页面时无法返回上一级页面

    NSUserDefaults*pushJudge = [NSUserDefaults standardUserDefaults];

    [pushJudge setObject:@""forKey:@"push"];

    [pushJudge synchronize];

    [self dismissViewControllerAnimated:YES completion:nil];

    }

就是在本地存储NSUserDefaults中存储用来判断是否是点击推送进入页面的,这个判断值是在goToMssageViewControllerWith:(上面找)方法中存入的,即进入相应页面之前先设置这个值,

    - (void)goToMssageViewControllerWith:(NSDictionary*)msgDic

    {

    //将字段存入本地

    NSUserDefaults*pushJudge = [NSUserDefaults standardUserDefaults];

    [pushJudge setObject:@"push"forKey:@"push"];

    [pushJudge synchronize];

    NSIntegerEventID = [[msgDic objectForKey:@"eventId"] integerValue];

    switch(EventID) {

    ...

       }

    }

这样就能达到基本一样的相应页了,点击返回的话是返回之前应用退入后台时的那个页面

B.如何进入tabbar的其中一个标签页面

这个其实很简单的,因为这个肯定不会跟上级页面有什么关联,我用的方法是重新把所有的标签页面存入一个tabbar中,然后present过去就好了;

    RootTabBarController*tabBarController = [RootTabBarController new]; 

    UINavigationController*AAController = [[UINavigationController alloc] initWithRootViewController:[AAViewController new]];

    UINavigationController*BBController = [[UINavigationController alloc] initWithRootViewController:[BBViewController new]];

    UINavigationController*CCController = [[UINavigationController alloc] initWithRootViewController:[CCViewController new]];

    NSArray*array_controllers = [NSArray arrayWithObjects:AAController,BBController,CCController,nil];

    tabBarController.viewControllers= array_controllers;

    tabBarController.selectedViewController= [tabBarController.viewControllersobjectAtIndex:];

    [tabBarControllersetSelBtn:];

    [self.window.rootViewControllerpresentViewController:tabBarControlleranimated:YEScompletion:nil];

以上就是简陋方法;

转自:简书,作者: 杏仁丶

链接:http://www.jianshu.com/p/8b70e4124fc9

iOS 关于信鸽推送点击推送通知的处理的更多相关文章

  1. iOS极光推送 点击推送消息跳转页面

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...

  2. iOS点击推送消息跳到应用指定页面

    现在的推送用的越来越频繁,几乎每个应用都开始用到了.其实又有几个用户会去看推送消息呢?没办法,产品经理最大啊,只是苦了我们这一帮程序员啊!闲话少说,进入正题.兄弟我用的是极光推送,自然是以极光推送为例 ...

  3. 点击推送消息跳转处理(iOS)

    当用户点击收到的推送消息时候,我希望打开APP,并且跳转到对应的界面,这就需要在AppDelegate里面对代理方法进行处理. 当用户点击推送消息打开APP的时候会调用 - (BOOL)applica ...

  4. IOS 推送-客户端处理推送消息

    IOS 推送-客户端处理推送消息 1.推送调用顺序 APN push的消息到达后,UIApplicationDelegate有两个方法和处理消息有关: 1)application:didReceive ...

  5. IOS之推送通知(本地推送和远程推送)

    推送通知和NSNotification是有区别的: NSNotification:是看不到的 推送通知:是可以看到的 IOS中提供了两种推送通知 本地推送通知:(Local Notification) ...

  6. 【记录】iOS10 点击推送栏的问题

    之前做的一个用户点击 推送栏然后处理相应事件是在这里面处理的 - (void)application:(UIApplication *)application didReceiveRemoteNoti ...

  7. 81、iOS本地推送与远程推送详解

    一.简介 分为本地推送和远程推送2种.可以在应用没打开甚至手机锁屏情况下给用户以提示.它们都需要注册,注册后系统会弹出提示框(如下图)提示用户石否同意,如果同意则正常使用:如果用户不同意则下次打开程序 ...

  8. iOS本地推送与远程推送

    原文在此 分为本地推送和远程推送2种.可以在应用没有打开甚至手机锁屏情况下给用户以提示.它们都需要注册,注册后系统会弹出提示框(如下图)提示用户是否同意,如果同意则正常使用:如果用户不同意则下次打开程 ...

  9. Swift - 推送之本地推送(UILocalNotification)添加Button的点击事件

    上一篇讲到的本地推送是普通的消息推送,本篇要讲一下带按钮动作的推送消息 import UIKit @UIApplicationMain class AppDelegate: UIResponder, ...

随机推荐

  1. 百度地图Api进阶教程-创建标注和自定义标注3.html

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="ini ...

  2. nginx日志request_time 和upstream_response_time区别

    笔者在根据nginx的accesslog中$request_time进行程序优化时,发现有个接口,直接返回数据,平均的$request_time也比较大.原来$request_time包含了用户数据接 ...

  3. idea破解,idea激活,使用破解补丁无需注册码

    dea激活,JetBrain旗下软件激活 前言 idea激活有多种方式,网上较多的是使用注册码或者填License server网址,目前(2017年8月19日)使用注册码的方式,亲测可用的只有lan ...

  4. 【转】【Html】Vuejs2.0学习之二(Render函数,createElement,vm.$slots,函数化组件,模板编译,JSX)

    1.Render函数 所以直接来到Render,本来也想跳过,发现后面的路由貌似跟它还有点关联.先来看看Render 1.1 官网一开始就看的挺懵的,不知道讲的是啥,动手试了一下,一开头讲的是Rend ...

  5. selenium+java-查找页面中包含关键字的URL

    package seleniumLearn1; import java.io.File; import java.io.FileOutputStream; import java.io.IOExcep ...

  6. Android Studio 出现 Build gradle project info

    导入Android Studio,一直停留在Build gradle project info.主要是因为google被墙,下载gradle很慢,有时候设置下载不成功. 参考链接 http://blo ...

  7. 部署基于Maven的war文件到Tomcat

    在本教程中,我们将学习如何使用Maven的Tomcat插件打包并部署一个WAR文件到Tomcat(Tomcat的6和7. 要用到工具: Maven 3 Tomcat 6.0.37 Tomcat 7.0 ...

  8. Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.【转】

    今天碰到了一个查询异常问题,上网查了一下,感谢原创和译者 如果你使用的数据库连接类是 the Data Access Application Blocks "SqlHelper" ...

  9. (转)Live555中RTSPClient分析

    有RTSPServer,当然就要有RTSPClient. 如果按照Server端的架构,想一下Client端各部分的组成可能是这样:因为要连接RTSP server,所以RTSPClient要有TCP ...

  10. kubectl error: The connection to the server localhost:8080 was refused

    did you run below commands after kubeadm init To start using your cluster, you need to run (as a reg ...