iOS推送,看这篇足够了
一、注册推送:
- (void)registerNotification
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0)
{
if (@available(iOS 10.0, *)) {
UNUserNotificationCenter * center =[UNUserNotificationCenter currentNotificationCenter];
center.delegate=self;
UNAuthorizationOptions options = UNAuthorizationOptionAlert|UNAuthorizationOptionSound|UNAuthorizationOptionBadge|UNAuthorizationOptionCarPlay;
[center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
}else{
NSLog(@"授权失败");
}
}];
} else {
// Fallback on earlier versions
}
}
else if ([[[UIDevice currentDevice] systemVersion] floatValue]>=8.0)
{
UIUserNotificationSettings *sets= [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:sets];
}
else
{
UIRemoteNotificationType type = UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:type];
}
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
假如用户第一次安装拒绝推送需要提醒的,按以下方法:(例子:iOS10 )
UNUserNotificationCenter *userNotificationCenter = [UNUserNotificationCenter currentNotificationCenter];
userNotificationCenter.delegate = self;
//获取通知设置信息
[userNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
//用户还未做出选择
if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
//弹出授权框
[userNotificationCenter requestAuthorizationWithOptions:UNAuthorizationOptionAlert + UNAuthorizationOptionBadge + UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
}else{
//首次授权为未授权状态,之后为已授权状态
DLog(@"没有开启通知");
}
}];
}else if (settings.authorizationStatus == UNAuthorizationStatusDenied){
//用户不同意授权时,弹出提示(最好只弹一次)
UIAlertController *noticeNotificationAlertController = [UIAlertController alertControllerWithTitle:@"友情提示" message:@"建议您开启通知功能,以便及时获取相关信息" preferredStyle:UIAlertControllerStyleAlert];
[noticeNotificationAlertController addAction:[UIAlertAction actionWithTitle:@"忽略" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}]];
[noticeNotificationAlertController addAction:[UIAlertAction actionWithTitle:@"去开启" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
NSURL *appSettingsUrl = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:appSettingsUrl]) {
[[UIApplication sharedApplication] openURL:appSettingsUrl];
}
}]];
[self.window.rootViewController presentViewController:noticeNotificationAlertController animated:YES completion:NULL];
}else{
//已授权
DLog(@"已授权通知");
}
}];
二、本地推送:
iOS10之后:
//使用 UNNotification 本地通知
+(void)registerNotification:(NSInteger )alerTime{
// 使用 UNUserNotificationCenter 来管理通知
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
//需创建一个包含待通知内容的 UNMutableNotificationContent 对象,注意不是 UNNotificationContent ,此对象为不可变对象。
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:@"Hello!" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:@"Hello_message_body"
arguments:nil];
content.sound = [UNNotificationSound defaultSound];
// 在 alertTime 后推送本地推送
UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger
triggerWithTimeInterval:alerTime repeats:NO];
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond"
content:content trigger:trigger];
//添加推送成功后的处理!
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"本地通知" message:@"成功添加推送" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancelAction];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}];
}
iOS10以前:
+ (void)registerLocalNotificationInOldWay:(NSInteger)alertTime {
UILocalNotification *notification = [[UILocalNotification alloc] init];
// 设置触发通知的时间
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:alertTime];
NSLog(@"fireDate=%@",fireDate);
notification.fireDate = fireDate;
// 时区
notification.timeZone = [NSTimeZone defaultTimeZone];
// 设置重复的间隔
notification.repeatInterval = kCFCalendarUnitSecond;
// 通知内容
notification.alertBody = @"该起床了...";
notification.applicationIconBadgeNumber = 1;
// 通知被触发时播放的声音
notification.soundName = UILocalNotificationDefaultSoundName;
// 通知参数
NSDictionary *userDict = [NSDictionary dictionaryWithObject:@"开始学习iOS开发了" forKey:@"key"];
notification.userInfo = userDict;
// 通知重复提示的单位,可以是天、周、月
notification.repeatInterval = NSDayCalendarUnit;
// 将本地通知添加到调度池,定时发送
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
// 立即发送
// [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
本地通知相关代理方法:
// 当App在前台状态下,如果有通知会调用该方法
// 当应用程序在后台状态下,点击推送通知,程序从后台进入前台后,会调用该方法(从锁屏界面点击推送通知从后台进入前台也会执行)
// 当应用程序完全退出时不调用该方法
- (void)application:(UIApplication *)application didReceiveLocalNotification:(nonnull UILocalNotification *)notification{
NSLog(@"%@", notification);
// 处理点击通知后对应的业务
UIApplicationState applicationState = [[UIApplication sharedApplication] applicationState];
if (applicationState == UIApplicationStateActive) {
// 前台
// 例如QQ会增加tabBar上的badgeValue未读数量
}
else if (applicationState == UIApplicationStateInactive) {
// 从前台进入后台
// 例如QQ会打开对应的聊天窗口
NSInteger applicationIconBadgeNumber = application.applicationIconBadgeNumber - 1;
application.applicationIconBadgeNumber = applicationIconBadgeNumber >= 0 ? applicationIconBadgeNumber : 0;
}
[application cancelLocalNotification:notification];
}
// 监听附加操作按钮
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(nonnull UILocalNotification *)notification completionHandler:(nonnull void (^)())completionHandler {
NSLog(@"identifier:%@", identifier); completionHandler();
}
// 该方法在iOS9.0后调用,iOS9.0之前调用上面那个方法
- (void)application:(UIApplication *)app handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(nonnull UILocalNotification *)notification withResponseInfo:(nonnull NSDictionary *)responseInfo completionHandler:(nonnull void (^)())completionHandler {
// ====identifier:no, content:{UIUserNotificationActionResponseTypedTextKey = "not agree";}
NSLog(@"====identifier:%@, content:%@", identifier, responseInfo);
completionHandler();
}
三、远程通知:
1、什么是远程推送
在联网的情况下,由远程服务器推送给客户端的通知,又称APNs(Apple Push Notification Services)不管应用是打开还是关闭的情况下,都能接收到服务器推送的远程通知在联网状态下,所有苹果设备都会与苹果服务器建立长连接
2、远程推送的实现原理:
1.打开App时: 发送UDID
和BundleID
给APNs
加密后返回deviceToken
2.获取Token
后,App调用接口,将用户身份信息和deviceToken
发给服务器,服务器记录
3.当推送消息时, 服务器按照用户身份信息找到存储的deviceToken
,将消息和deviToken
发送给APNs
4.苹果的APNs通过deviceToken
, 找到指定设备的指定程序, 并将消息推送给用户
3、实现远程推送功能的前提
1.真机
2.调试阶段的证书
iOS_development.cer
用于真机调试的证书
aps_development.cer
用于真机推送调试能的证书
xxx.mobileprovision
描述文件,记录了能够调试的手机、电脑和程序
3.发布阶段的证书
iOS_distribution.cer
用于发布app的证书
aps.cer
用于发布时,让app有推送功能的证书
xxx.mobileprovision
描述文件,记录了能够发布app的电脑
如何配置证书, 不在本教程内, 请读者自行处理, 或者参考视频教程
一、 注册远程推送并获取DeviceToken
1.创建iOS的项目,并输入项目名字
2.在AppDelegate
中导入头文件:
#import <UserNotifications/UserNotifications.h>
3.在application:didFinishLaunchingWithOptions
方法中, 注册远程通知
- (
BOOL
)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//请求通知权限, 本地和远程共用
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert completionHandler:^(
BOOL
granted, NSError * _Nullable error) {
if
(granted) {
NSLog(@
"请求成功"
);
}
else
{
NSLog(@
"请求失败"
);
}
}];
//注册远程通知
[[UIApplication sharedApplication] registerForRemoteNotifications];
//设置通知的代理
center.delegate = self;
return
YES;
}
4.在接收远程推送的DeviceToken
方法中, 获取Token
1
2
3
4
5
- (
void
)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
//将来需要将此Token上传给后台服务器
NSLog(@
"token:%@"
, deviceToken);
}
二、 iOS10之前通知的处理方法
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
//此方法已被下面的方法代替
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
//iOS10之前,接收远程通知时,不管在前台、后台还是程序杀死都会调用此方法
if (application.applicationState == UIApplicationStateActive) {
// 前台收到通知处理
}else{
//后台或退出时点击通知处理
}
completionHandler();
}
三、 iOS10远程推送通知的处理方法
当点击了推送后, 如果你希望进行处理. 那么在iOS10中, 还需要设置UNUserNotificationCenter
的delegate
, 并遵守UNUserNotificationCenterDelegate
协议.
以及实现下面实现3个方法, 用于处理点击通知时的不同情况的处理
willPresentNotification:withCompletionHandler
用于前台运行
didReceiveNotificationResponse:withCompletionHandler
用于后台及程序退出
didReceiveRemoteNotification:fetchCompletionHandler
用于静默推送
1
2
//设置通知的代理
center.delegate = self;
1.前台运行 会调用的方法
前台运行: 指的是程序正在运行中, 用户能看见程序的界面.
iOS10会出现通知横幅, 而在以前的框架中, 前台运行时, 不会出现通知的横幅.
1
2
3
4
5
6
7
8
9
10
- (
void
)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(
void
(^)(UNNotificationPresentationOptions))completionHandler
{
NSDictionary *userInfo = notification.request.content.userInfo;
//前台运行推送 显示红色Label
[self showLabelWithUserInfo:userInfo color:[UIColor redColor]];
//可以设置当收到通知后, 有哪些效果呈现(声音/提醒/数字角标)
completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
}
2.后台运行及程序退出 会调用的方法
后台运行: 指的是程序已经打开, 用户看不见程序的界面, 如锁屏和按Home键.
程序退出: 指的是程序没有运行, 或者通过双击Home键,关闭了程序.
1
2
3
4
5
6
7
8
9
|
- ( void )userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:( void (^)())completionHandler { NSDictionary *userInfo = response.notification.request.content.userInfo; //后台及退出推送 显示绿色Label [self showLabelWithUserInfo:userInfo color:[UIColor greenColor]]; completionHandler(); } |
3.静默推送通知 会调用的方法
静默推送: iOS7以后出现, 不会出现提醒及声音.
要求:
推送的payload
中不能包含alert
及sound
字段
需要添加content-available
字段, 并设置值为1
例如: {"aps":{"content-available":"1"},"PageKey”":"2"}
1
2
3
4
5
6
7
8
|
//如果是以前的旧框架, 此方法 前台/后台/退出/静默推送都可以处理 - ( void )application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:( void (^)(UIBackgroundFetchResult))completionHandler { //静默推送 显示蓝色Label [self showLabelWithUserInfo:userInfo color:[UIColor blueColor]]; completionHandler(UIBackgroundFetchResultNewData); } |
4.处理通知的公用方法
开发中, 点击通知的逻辑应当看自己程序的需求.
这里为了方便演示, 简单的将通知的值, 通过UILabel
显示在主界面上.
1
2
3
4
5
6
7
8
9
|
- ( void )showLabelWithUserInfo:(NSDictionary *)userInfo color:(UIColor *)color { UILabel *label = [UILabel new ]; label.backgroundColor = color; label.frame = CGRectMake(0, 250, [UIScreen mainScreen].bounds.size.width, 300); label.text = userInfo.description; label.numberOfLines = 0; [[UIApplication sharedApplication].keyWindow addSubview:label]; } |
iOS推送,看这篇足够了的更多相关文章
- 基于APNs最新HTTP/2接口实现iOS的高性能消息推送(服务端篇)
1.前言 本文要分享的消息推送指的是当iOS端APP被关闭或者处于后台时,还能收到消息/信息/指令的能力. 这种在APP处于后台或关闭情况下的消息推送能力,通常在以下场景下非常有用: 1)IM即时通讯 ...
- iOS 推送全解析
本文旨在对 iOS 推送(以下简称 推送)进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解.以下是 pikacod ...
- 一步一步教你做ios推送
最近在研究ios的推送问题,遇到了一些问题,最终整理了一下.放在这里和大家分享 APNS的推送机制 首先我们看一下苹果官方给出的对ios推送机制的解释.如下图 Provider就是我们自己程序的后台服 ...
- iOS 推送全解析,你不可不知的所有 Tips!
本文旨在对 iOS 推送进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解.以下是 pikacode 使用 iOS ...
- IOS 推送-配置与代码编写
IOS 推送配置与代码编写 这里介绍IOS的推送,本文章已经在IOS6/7/8上都能运行OK,按照道理IOS9应该没问题. 大纲: 1.文章前提 2.推送介绍 3.推送文件账号设置 4.推送证书介绍 ...
- “iOS 推送通知”详解:从创建到设置到运行
这是一篇编译的文章,内容均出自Parse.com的iOS开发教程,同时作者还提供了视频讲解.本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义. 介绍一点点背景资料 ...
- iOS推送 再备
这是一篇编译的文章,内容均出自Parse.com的iOS开发教程,同时作者还提供了视频讲解.本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义. 介绍一点点背景资料 ...
- 利用pyapns进行ios推送
ios客户端的同事提供了2个证书,分别是aps_development.cer 和 pushdevelopment.p12, 我最终目的就是把这2个证书合并成1个pem证书,然后通过pyapns进行 ...
- iOS推送的众多坑
新来的一家公司,昨天和同事解决推送问题(工程里有集成百度推送和环信即时通讯),信誓旦旦的声称:" app在前台和后台运行时,推送触发的是didReceiveRemoteNotificatio ...
- iOS 推送问题全解答《十万个为啥吖?》
Q 1:为啥收不到推送(1)? 如果收到推送时,App 在前台运行,那么: iOS 10 before 顶部横幅不会弹出.没有任何展示,你以为「没有收到推送」. iOS 10 after 如果没有实现 ...
随机推荐
- Collection和Map的默认扩容参数
初始大小:调用无参构造函数时默认的容量 加载因子:超过 (当前容量*加载因子) 时会进行扩容 扩容因子:扩容时增加的容量为 (当前容量*扩容因子) 容器 初始容量 ...
- C# 相对路径转绝对路径
如果是路径相对路径,使用 Path 转换 System.IO.Path.Combine(文件夹, relativePath); 文件夹就是相对的文件夹. 这样就可以把相对路径转绝对. 参见:http: ...
- 【转】NOR Flash擦写和原理分析
1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直接在FLASH片内执行(这意味着存 ...
- Kafka 学习笔记-基本概念
一.基本概念 Kafka是一个分布式的,可分区的,可复制的消息系统 Kafka以由一个或多个服务以集群的方式运行,服务叫broker producer,consuer通过kafka topic发布,预 ...
- Superset连接Impala数据源
公司最近在superset上面做二次开发,目前对接了mysql和oracle数据源,对这两个源的SQL操作查询做了完善和兼容.目前有新的需求就是要对接大数据部门的HBASE和HIVE数据源,由于sup ...
- 火狐浏览器打开html文件,中文乱码
当html文件为: 解决方法: 将 <meta http-equiv="Content-Type" content="text/html; charset=UT ...
- spark的sparkUI如何解读?
spark的sparkUI如何解读? 以spark2.1.4来做例子 Job - schedule mode 进入之后默认是进入spark job 页面 这个说明有很详细的解释,spark有两种操作算 ...
- Supervised Learning and Unsupervised Learning
Supervised Learning In supervised learning, we are given a data set and already know what our correc ...
- K - Kia's Calculation (贪心)
Kia's Calculation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- Best Coder #86 1001 Price List(大水题)
Price List Accepts: 880 Submissions: 2184 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 26214 ...