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

在这里我项目中所要达到的效果是点击通知栏的推送消息,就进入应用中的相应页;默认的效果是点击推送消息,会直接进入应用,如果应用未启动,则会启动应用进入首页如果应用已启动,只是点击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. 一圖讓你看懂javascript原型鏈

    每個對象的原型(protype)是一個對象 每個對象都有一個內置屬性protype(__pro__)指向一個對象

  2. 机器学习 demo分西瓜

    周老师的书,对神经网络写了一个小的Demo 是最简单的神经网络,只有一层的隐藏层. 这次练习依旧是对西瓜的好坏进行预测. 主要分了以下几个步骤 1.数据预处理 对西瓜的不同特性进行数学编码表示(0~1 ...

  3. DataFrame在算术方法中填充值

    在对不同索引的对象进行算术运算时, 你可能希望当一个对象中某个轴标签在另一个对象中找不到时填充一个特殊值(比如0)

  4. SpringBoot系列八:SpringBoot整合消息服务(SpringBoot 整合 ActiveMQ、SpringBoot 整合 RabbitMQ、SpringBoot 整合 Kafka)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合消息服务 2.具体内容 对于异步消息组件在实际的应用之中会有两类: · JMS:代表作就是 ...

  5. e861. 在两个组件之间共享输入映射和事件映射

    By sharing an InputMap or ActionMap, any change to the shared InputMap or ActionMap will affect all ...

  6. JavaScript数据去掉空值

    js数组中过滤掉false, null, 0, "", undefined, and NaN值的方法 对于 false,null,0,undefiend,NaN直接取!得到的都是t ...

  7. HTTP之referer

    安全培训中提到可以通过referer判断安全性,hackbar中也有一个enable referer的选项,则,这个referer到底是个什么角色? (以下是搜集的一些资料整合,链接均放到底部,不再一 ...

  8. NPOIHelp 按固定模板导出和直接导出

    完整代码如下 using System; using System.Collections.Generic; using System.Data; using System.Text; using N ...

  9. QtCore.QMetaObject.connectSlotsByName:根据objectName和signal自动绑定slot

    from PyQt5.QtWidgets import (QWidget , QVBoxLayout , QHBoxLayout, QLineEdit, QPushButton) from PyQt5 ...

  10. VS 附加进程调试 Web项目

    一.新建IIS站点物理路径要指定项目开发Web路径(不可以发布), 二.Host文件网站域名要指定127.0.0.1 三.打开项目目录找到.vs\config\applicationhost.conf ...