推送通知
1、作用:让不在前台(后台或者关闭)的APP知道APP内部发生的事情
2、在“设置”——>“通知中心”-----> 可以关闭推送通知
3、发送推送通知时,如果程序运行在前台,推送通知就不会呈现。
4、点击推送通知会打开对应的app
5、不管应用程序出于后台还是被杀死,推送通知都会发出
一、本地推送通知
概念:由APP本身给应用程序推送消息,不需要服务器的支持
常见场景:记账软件/闹钟/定时提醒记账/番茄工作法/系统电池没电中提醒你时间等等
注意:不是非常常用。
1、发送本地推送
//点击按钮发送本地通知
- (IBAction)fireLocalNoti {
//无论程序在前台、后台、退出了,都可以接收到本地通知
//1.创建本地通知
UILocalNotification *localNote = [[UILocalNotification alloc] init];
//2.设置通知显示的内容
//2.1.设置通知发出的时间,即5秒后发出通知
localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
//2.2.设置通知的内容
localNote.alertBody = @"吃饭了吗?";
//2.3.设置锁屏界面滑块下显示的文字
localNote.alertAction = @"聊天";
//2.4.决定alertAction是否生效
localNote.hasAction = NO;
//2.5.设置通知中心的标题
localNote.alertTitle = @"一般是app的名字";
//2.6.设置通知时的音效
localNote.soundName = UILocalNotificationDefaultSoundName;
//2.7.设置app右上角的数字
localNote.applicationIconBadgeNumber = 10;
//2.8.设置额外的信息,暂时没有用处
localNote.userInfo = @{@"name":@"张三", @"age":@23};
//2.9.本地通知的类型标志符,做快捷回复通知使用
localNote.category = @"11";
//2.10、通知重复调用的时间-->设置以后,则调度池不会自动销毁通知
localNote.repeatInterval = NSCalendarUnitMinute;
//3.调度通知,让通知在特定的时间发送本地通知,ios8.0以后才出现
[[UIApplication sharedApplication] scheduleLocalNotification:localNote];
//4、注册通知,ios8.0,请求用户权限的事情,如果只有一次,则在代码直接在代码处写,多次在appDelegate中写
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
//5、获取本地通知,并删除重复通知
//获取所有通知
// NSArray *notifcationArr = [[UIApplication sharedApplication] scheduledLocalNotifications];
// for (UILocalNotification *locationNoti in notifcationArr) {
// //可以根据userInfo来删除某个通知
// if (locationNoti.userInfo) {
// [[UIApplication sharedApplication] cancelLocalNotification:locationNoti];
// }
// }
}
- (IBAction)removeLocalNote {
//关闭所有的通知
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
2、在前台/后台接收到通知后进行跳转
//当(前台/后台)接收到一个本地通知时,会调用该方法
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
/**
* UIApplicationStateActive 前台
* UIApplicationStateInactive 进入前台
* UIApplicationStateBackground 后台
*/
if(application.applicationState == UIApplicationStateActive){
NSLog(@"在前台时,不要进行跳转;要么提示用户进行跳转");
//当然也可以跳转到指定界面
return;
}
//在后台进入前台时,跳转到某个固定的页面
NSLog(@"根据%@跳转到一个固定的页面:%s", notification.userInfo, __func__);
}
3、在应用程序被杀死时,接收到本地推送通知后进行跳转
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0){
//1.iOS8之后,如果想要发出通知(无论本地还是远程),必须先进行注册.(iOS8之前不需要)
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:setting];
}else{
//ios8.0之前的注册推送通知
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
}
//如果应用程序被杀死了,但是任然要实现接收到通知进行跳转,则需要在此处实现跳转。因为程序被杀死后,接收到通知不会调用didReceiveLocalNotification方法。
// 判断是否是通过点击通知打开了应用程序
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
// 跳转代码
NSLog(@"接收到本地通知,跳转到一个固定的界面");
}
return YES;
}
4、本地推送快捷回复调用的方法
通过分类来实现
//无论程序在前台、后台、退出了,都可以接收到本地通知
//1.创建本地通知
UILocalNotification *localNote = [[UILocalNotification alloc] init];
//2.9.本地通知的类型标志符
localNote.category = @"category";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//1、创建本地推送通知分类
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
//2、设置标志符
category.identifier = @"category";
//3、设置前台按钮
UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
action1.identifier = @"qiantai";
//3.1、设置前台按钮模式
action1.activationMode = UIUserNotificationActivationModeForeground;
//3.2、设置按钮的标题
action1.title = @"qiantai哈哈";
//3、设置后台按钮
UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
action2.identifier = @"houtai";
//3.1、设置前台按钮模式
action2.activationMode = UIUserNotificationActivationModeBackground;
//3.2、设置按钮的标题
action2.title = @"houtai哈哈";
//4、设置按钮
[category setActions:@[action1, action2] forContext:UIUserNotificationActionContextDefault];
//5、设置分类的集合
NSSet *categorySet = [NSSet setWithObject:category];
if([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0){
//1.iOS8之后,如果想要发出通知(无论本地还是远程),必须先进行注册.(iOS8之前不需要)
/**
* @param types:显示收到本地通知时的样式
* UIUserNotificationTypeNone 无
* UIUserNotificationTypeBadge app图像显示通知的数字
* UIUserNotificationTypeSound 声音
* UIUserNotificationTypeAlert 弹窗
*
*/
//6、设置分类集合
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:categorySet];
[application registerUserNotificationSettings:setting];
}else{
//ios8.0之前的注册推送通知
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
}
return YES;
}
//处理分类按钮调用的方法
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
NSLog(@"根据标识符进行逻辑操作%@", identifier);
//一旦接收到本地推送通知,必需调用,告诉系统进行资源分配
completionHandler();
}
二、远程推送
1、概念
概念:由服务器推送消息给用户,弹出消息的通知(需要联网),需要服务器的支持。远程推送服务,又称为APNs(Apple PushNotification Services)。
常见场景:微信提醒新消息/淘宝提醒有新活动/视频软件提供您有最新电影
注意:非常常用.但是如果仅仅是给用户提醒,客户端(你)做的事情就非常简单.
例子:淘宝最近双11搞活动,各种送红包,想告知用户.但是该用户不经常打包淘宝APP.淘宝如何通知该用户有最新的活动呢?
传统方式(以前):只有用户打开了淘宝客户端,客户端向服务器请求是否有最新的活动,才能在APP中告知用户活动。
传统方式局限性:只要用户关闭了app,就无法跟app的服务器沟通,无法从服务器上获得最新的数据内容。
远程推送通知的好处:不管用户打开还是关闭app,只要联网了,都能接收到服务器推送的远程通知。
2、原理
远程通知的原理:淘宝服务器把“红包活动” --> 推送 --> 苹果的APNs服务器 --> 推送 --> 淘宝客户端app
2.1、为什么淘宝服务器不直接推消息给用户?
在通常情况下服务器端是不能主动向客户端推消息的。
如果想服务器端给客户端推消息,必须建立长连接,淘宝客户端在处于后台时不能和服务器端建立长连接。
2.2、为什么苹果服务器可以推消息给用户?
所有的苹果设备,在联网状态下,都会与苹果的服务器建立长连接
苹果建立长连接的作用:时间校准、系统升级提示、查找我的iPhone、远程推送通知
短链接:客户端app给服务器发送请求,服务器返回数据,客户端app收到数据,链接断开。此时,服务器则不能给客户端推送消息。
长链接:通过socket来建立。即时通讯中使用。建立长链接对服务器的负荷特别大。高并发后台人才的技术,可以节省服务器。
2.3、苹果在推送消息时,如何准确的推送给某一个用户,并且知道是哪一个APP?
在淘宝服务器把消息给苹果的APNs服务器时,必须告知苹果DeviceToken
什么是DeviceToken?
DeviceToken是由用户手机的UDID和应用程序的BundleID共同生成的
通过DeviceToken可以找到唯一手机中的唯一应用程序
如何获得DeviceToken?
客户端到苹果的APNs注册即可获得。
2.4、如何实现远程推送通知
首先,BundleID对应的APPID必须是明确的(特殊功能)
该APPID必须配置两个证书
调试证书:用于调试远程推送
发布证书:用于发布后给用户推送消息
根据上面的APPID重新配置描述文件
安装对应的证书,即可开始测试远程推送
3、苹果自带的远程推送通知
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if([[UIDevice currentDevice].systemVersion doubleValue]>= 8.0){
//注册推送通知
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:settings];
//注册远程通知,获取DeviceToken
[application registerForRemoteNotifications];
}else{
//ios8.0之前的注册推送通知
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
}
//如果应用程序被杀死了,但是任然要实现接收到通知进行跳转,则需要在此处实现跳转。因为程序被杀死后,接收到通知不会调用didReceiveRemoteNotification方法。
// 判断是否是通过点击通知打开了应用程序
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
// 跳转代码
NSLog(@"接收到本地通知,跳转到一个固定的界面");
//获取通知的消息
NSDictionary *remoteDict = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
}
return YES;
}
//通过代理方法获取deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
//deviceToken:用于发送给公司的服务器,让公司的服务器作存储
NSLog(@"%@", deviceToken);
/**
* UIApplicationStateActive 前台
* UIApplicationStateInactive 进入前台
* UIApplicationStateBackground 后台
*/
if(application.applicationState == UIApplicationStateActive){
NSLog(@"在前台时,不要进行跳转");
return;
}
NSLog(@"跳转到一个固定的页面:%s", __func__);
}
#pragma mark - 当接收到远程推送时,调用该方法
//前台/后台时,可以在此方法接收到通知,在杀死时需要在didFinishLaunchingWithOptions
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSLog(@"%@", userInfo);
}
#pragma mark - 当接收到远程推送时,调用该方法,ios7推出
//前台/后台/退出时,可以在此方法接收到通知
//如果此方法和“application:didReceiveRemoteNotification:”方法都实现,则此方法有效,另外一个方法无效
//如果实现了此方法,还需要打开一个选项值 --> 点击项目 --> capabilites --> backgroundModes --> remoteNotification,即打开了后台远程通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
//必须调用一下block,否则报错。此block告诉苹果服务器推送是否成功
// UIBackgroundFetchResultNewData
// UIBackgroundFetchResultNoData
// UIBackgroundFetchResultFailed
completionHandler(UIBackgroundFetchResultNewData);
}
三、第三方平台的远程推送通知
友盟、极光推送
推送的作用非常简单,就是将我们服务器需要做的事情用激光推送服务器作为替代。
极光推送给任何用户不需要交钱,但是如果推送给特定的用户则需要交钱。