本地通知:就是指不需要互联网就能发出的推送通知(不需要服务器去支持),使用的场景一般是定时提醒用户完成一些任务,例如清理垃圾,看定影,记账等。在IOS8之后本地通知还需要注册用户权限。
通知行为:前台通知行为,后台通知行为
设置本地通知属性(推荐一个一个属性测试运行)
// 1.设置通知的内容(如果此属性不设置是不会发送通知的)
ln.alertBody = @"小明,你妈叫你回家吃饭了!";
// 2.设置通知触发的开始时间
ln.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
// 3.设置重复通知的时间,间隔
ln.repeatInterval = NSCalendarUnitSecond;
// 4.设置重复执行使用日历(用户设置的日历)
ln.repeatCalendar = [NSCalendar currentCalendar];
// NSString * const NSGregorianCalendar; 公历
// NSString * const NSChineseCalendar; 农历
// ln.repeatCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSChineseCalendar];
// 5.设置应用图标右上角的数字
ln.applicationIconBadgeNumber = 3;
// 6.设置点击推送通知进入界面的时候显示,加载图片
ln.alertLaunchImage = @"";
// 7 设置通知的音效(只有真机有效)
local.soundName = UILocalNotificationDefaultSoundName;
// 8 设置一些额外信息
local.userInfo = @{@"QQ":@"55555",@"info":@"约了没"};
// iOS8.0 以后新增属性
// ************************************
// 1.设置区域,进入或离开某个区域的时候触发
// CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(40.1,106.1);
// ln.region = [[CLCircularRegion alloc] initWithCenter:coordinate radius:10.0 identifier:@"ab"];
// 2.设置进入或离开某个区域只执行一次
// ln.regionTriggersOnce = YES;
// ***************************************
// iOS8.2 新增属性
// ln.alertTitle = @"通知标题";
AppDelegate本地通知代理方法:
* 一旦接收到本地通知就会调用该方法
* 注意这个方法:应用在前台也会调用
* @param application 应用
* @param notification 本地通知对象
- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
// 当应用在前台时候什么都不做
if (application.applicationState == UIApplicationStateActive) {
return;
}
// 当应用不再前台的时候才去跳转,这样用户体检更好
UITabBarController *tbVc = (UITabBarController *)application.keyWindow.rootViewController;
tbVc.selectedIndex = 1;
}
但是当应用被干掉的时候,不在调用application:didReceiveLocalNotification:的代理方法,但我们知道当应用程序启动的时候一定会调用application: didFinishLaunchingWithOptions:的代理方法,在这里我们能拿到本地通知信息,也可以跳转相应的界面
// 如果是点击本地通知进来的那么launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]就会有内容
if(launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]){
//页面跳转
UITabBarController *tbVc = (UITabBarController *)self.window.rootViewController;
tbVc.selectedIndex = 1;
}
点击不同的通知跳转不同的界面的方法:
在发送通知时候,设置userInfo属性
// 设置应用信息
ln.userInfo = @{@"pageKey":@"friend"};
在AppDelegate本地通知代理方法中进行判断
/**
* 一旦接收到本地通知就会调用该方法
* 注意这个方法:应用在前台也会调用
* @param application 应用
* @param notification 本地通知对象
*/
- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// 当应用在前台时候什么都不做
if (application.applicationState == UIApplicationStateActive) {
return;
}
// 当应用不再前台的时候才去跳转,这样用户体检更好
// 获取tabBarController
UITabBarController *tbVc = (UITabBarController *)self.window.rootViewController;
// 获取用户设置的跳转页
NSString *page = notification.userInfo[@"pageKey"];
// 如果是朋友圈
if ([page isEqualToString:@"session"]) {
tbVc.selectedIndex = 1;
}else{
// 否则跳转到好友
tbVc.selectedIndex = 0;
}
}
我们取出UILocalNotification对象,剩下的做法与接收到本地通知代理方法中处理相同,所以我们把它提取为一个公用的方法
/**
* 根据通知跳转到不同页面
*/
- (void) jumpToPageWithLocalNotification:(UILocalNotification *) notification
{
// 获取tabBarController
UITabBarController *tbVc = (UITabBarController *)self.window.rootViewController;
// 获取用户设置的跳转页
NSString *page = notification.userInfo[@"pageKey"];
// 如果是朋友圈
if ([page isEqualToString:@"session"]) {
tbVc.selectedIndex = 0;
}else{
// 否则跳转到好友
tbVc.selectedIndex = 1;
}
}
在didReceiveLocalNotification方法中
/**
* 一旦接收到本地通知就会调用该方法
* 注意这个方法:应用在前台也会调用
* @param application 应用
* @param notification 本地通知对象
*/
- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// 当应用在前台时候什么都不做
if (application.applicationState == UIApplicationStateActive) {
return;
}
// 当应用不再前台的时候才去跳转,这样用户体检更好
[self jumpToPageWithLocalNotification:notification];
}
在didFinishLaunchingWithOptions方法中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// 如果是点击本地通知进来的那么launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]就会有内容
UILocalNotification *notifcation = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
// 如果存在通知
if(notifcation){
[self jumpToPageWithLocalNotification:notifcation];
}
return YES;
}
用户点击本地推送通知,会自动打开APP,分为两种情况:
app并没有关闭,一直隐藏在后台,让app进入前台,并会调用AppDelegate的下面方法(并非重新启动app)
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
app已经被关闭(进程已死)启动app,启动完毕会调用AppDelegate的下面方法
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
aunchOptions参数通过UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知对象
基于位置的通知:当用户进入或者离开某个位置就会发送通知(IOS8之后才有的),需要设置requestWhenInUseAuthorization
远程通知:顾名思义,就是从远程服务器推送给客户端的通知(需要联网),远程推送服务,又称为APNs(ApplePush Notification Services),为什么要使用远程通知?因为用户关闭了APP就无法收到服务器最新的数据,但是远程通知服务可以无视用户APP是否开启,只要联网了,就能收到服务器远程推送的通知。
远程通知的示意图:
•所有的苹果设备,在联网状态下,都会与苹果的服务器建立长连接
什么是长连接:只要联网了,就一直建立连接
长连接的作用 1.时间校准 2.系统升级 3.查找我的iPhone
长连接的好处 1.数据传输速度快 2.数据保持最新状态
实现远程推送通知的过程
1 真机
2 证书
开发阶段
aps_development.cer 让某个电脑具备调试远程推送通知的能力
ios_development.cer 让某个电脑具有真机调试的能力
dev_qq.mobileprovision 让某个电脑上可以在某个真机上调试某个App的远程推送服务
发布阶段
aps_production.cer 让电脑具备发布某个具有远程推送服务的App的能力
ios_distribution.cer 让电脑具备发布程序的能力
dis_qq.mobileprovision 让某台电脑具备发布某App的能力
从APNs服务器上获取deviceToken
配置远程推送通知证书
远程推送代码实现
在iOS7下
注册远程通知
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// UIRemoteNotificationTypeBadge = 1 << 0, 应用图标右上角数字
// UIRemoteNotificationTypeSound = 1 << 1, 声音
// UIRemoteNotificationTypeAlert = 1 << 2, 提示
// UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3, 新闻,国内几乎没人使用
// 远程通知类型
UIRemoteNotificationType remoteTypes = UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert;
// 注册远程通知(在iOS8被废弃了)
[application registerForRemoteNotificationTypes:remoteTypes];
return YES;
}
实现注册远程通知返回deviceToken的回调方法
/**
* 当APNs返回deviceToken会调用,该方法
*
* @param application 当前应用对象
* @param deviceToken 设备令牌
*/
- (void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"%@",deviceToken);
}
实现注册远程通知失败回调方法,用于检查失败原因方便调试
/**
* 当从APNs获取deviceToken失败的时候会回调该方法
*
* @param application 应用
* @param error 错误
*/
- (void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"%@",error);
}
实现点击远程通知,进入App调用的方法
/**
* 处理点击远程通知的页面跳转处理
*/
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(@"%s",__FUNCTION__);
}