一、简介

分为本地推送和远程推送2种。可以在应用没打开甚至手机锁屏情况下给用户以提示。它们都需要注册,注册后系统会弹出提示框(如下图)提示用户石否同意,如果同意则正常使用;如果用户不同意则下次打开程序也不会弹出改提示框,需要用户到设置里面设置。一共有三种提示类型:

UIUserNotificationTypeBadge:应用图标右上角的信息提示

UIUserNotificationTypeSound:播放提示音

UIUserNotificationTypeAlert:提示框

二、本地推送

1.注册与处理

代码如下:

/// 一般在在启动时注册通知,程序被杀死,点击通知后调用此程序
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

- (void)registerAPN {

// 注册通知

if (@available(iOS 10.0, *)) { // iOS10 以上

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {

}];

} else {// iOS8.0 以上

UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];

[[UIApplication sharedApplication] registerUserNotificationSettings:setting];

}

}


return YES;
}
/// 程序没有被杀死(处于前台或后台),点击通知后会调用此程序
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
// 这里添加处理代码
}

可以看到,处理代码有两个方法,一个是

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
另一个是
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
如果程序没有被杀死,即处于前台或者后台,那么调用前者;如果程序被杀死,则调用后者。

- (void)applicationWillResignActive:(UIApplication *)application {

#pragma mark -->NSLog(@"\n ===> 程序挂起 !");  比如:当有电话进来或者锁屏,这时你的应用程会挂起,在这时,UIApplicationDelegate委托会收到通知,调用 applicationWillResignActive 方法,你可以重写这个方法,做挂起前的工作,比如关闭网络,保存数据。

}

- (void)applicationDidEnterBackground:(UIApplication *)application {

#pragma mark --> NSLog(@"\n ===> 程序进入后台 !");

}

- (void)applicationWillEnterForeground:(UIApplication *)application {

#pragma mark --> NSLog(@"\n ===> 程序进入前台 !");

[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];

}

- (void)applicationDidBecomeActive:(UIApplication *)application {

#pragma mark -->  NSLog(@"\n ===> 程序重新激活 !"); 应用程序在启动时,在调用了 applicationDidFinishLaunching 方法之后也会调用 applicationDidBecomeActive 方法,所以你要确保你的代码能够分清复原与启动,避免出现逻辑上的bug。(大白话就是说:只要启动app就会走此方法)。

}

- (void)applicationWillTerminate:(UIApplication *)application {

#pragma mark --> 当用户按下按钮,或者关机,程序都会被终止。当一个程序将要正常终止时会调用 applicationWillTerminate 方法。但是如果长主按钮强制退出,则不会调用该方法。这个方法该执行剩下的清理工作,比如所有的连接都能正常关闭,并在程序退出前执行任何其他的必要的工作.

}

2.发送通知

- (void)addLocalNotice {

if (@available(iOS 10.0, *)) {

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];

// 标题

content.title = @"测试标题";

content.subtitle = @"测试通知副标题";

// 内容

content.body = @"测试通知的具体内容";

// 声音

//        content.sound = [UNNotificationSound defaultSound];

content.sound = [UNNotificationSound soundNamed:@"Alert_ActivityGoalAttained_Salient_Haptic.caf"];

// 角标 (我这里测试的角标无效,暂时没找到原因)

content.badge = @1;

// 多少秒后发送,可以将固定的日期转化为时间

NSTimeInterval time = [[NSDate dateWithTimeIntervalSinceNow:2] timeIntervalSinceNow];

//        NSTimeInterval time = 10;

// repeats,是否重复,如果重复的话时间必须大于60s,要不会报错

UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:time repeats:NO];

/*

//如果想重复可以使用这个,按日期

// 周一早上 8:00 上班

NSDateComponents *components = [[NSDateComponents alloc] init];

// 注意,weekday默认是从周日开始

components.weekday = 2;

components.hour = 8;

UNCalendarNotificationTrigger *calendarTrigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];

*/

// 添加通知的标识符,可以用于移除,更新等操作

NSString *identifier = @"noticeId";

UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];

[center addNotificationRequest:request withCompletionHandler:^(NSError *_Nullable error) {

NSLog(@"成功添加推送");

}];

}else {

UILocalNotification *notif = [[UILocalNotification alloc] init];

// 发出推送的日期

notif.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];

// 推送的内容

notif.alertBody = @"你已经10秒没出现了";

// 可以添加特定信息

notif.userInfo = @{@"noticeId":@"00001"};

// 角标

notif.applicationIconBadgeNumber = 1;

// 提示音

notif.soundName = UILocalNotificationDefaultSoundName;

// 每周循环提醒

notif.repeatInterval = NSCalendarUnitWeekOfYear;

[[UIApplication sharedApplication] scheduleLocalNotification:notif];

}

}

3. 取消通知

// 取消所有本地通知
[application cancelAllLocalNotifications]; 三、远程推送

与Android上我们自己实现的推送服务不一样,Apple对设备的控制非常严格,消息推送的流程必须要经过APNs(Apple Push Notification service).

一般情况下如果一个程序退到后台就不能运行代码(Audio、VoIP等等可以在后台运行),或者程序退出后,那么它就和对应应用的后台服务器断开了链接,就收不到服务器发送的信息了,但是每台设备只要联网就会和苹果的APNs服务器建立一个长连接(persistent IP connection),这样只要通过苹果的APNs服务器,我们自己的服务器就可以间接的和设备保持连接了,示意图如下:

使用步骤:

1 勾选Backgroud Modes -> Remote notifications,主要是iOS7之后,苹果支持后台运行,如果这里打开后,当接收到远程推送后,程序在后台也可以做一些处理,如下图所示:

2.远程推送机制

你的应用服务端将消息发送到apple的APNS服务器,APNS服务器将消息推送到指定的Iphone,最后由Iphone负责将消息推送至你的APP。在此先不说这个过程是如何实现的,仅仅看这个流程,你可能会觉得,在你们服务端和客户端之间增加了一个apple的APNS,不是增加开发者的负担么?其实结果恰恰相反,因为apple对推送的统一管理,使我们开发者的工作变得异常简单。

3.服务端如何连接到客户端的

 如果你是做android开发的,你一定非常了解长链接与心跳包。事实上,大部分的android应用的推送也确实是通过长链接来实现的。因为android系统的开放性,APP是很容易做到自启动和后台长链接的,而心跳验证,就是始终保证长链接属于接通状态,然后由服务端直接推送消息。如果IOS开发者也采用这种思路,就十分困难了,在IOS中想要保持一个APP服务始终不被系统杀死,我只能说太难了。通过上面的流程图,对比android的推送思路,我们很容易明白,IOS中其实也始终有一个长链接,那就是系统本身,这个长链接始终与APNS服务器相连,然后统一管理所有应用程序的推送。

4.这是IOS推送机制的优势?

1、因为推送的服务端是appleID的验证用户,推送可靠性会高。

2、所有推送消息由APNS统一管理,效率高。

3、在客户端只需系统维护一个长链接,节省了用户流量消耗和手机的性能消耗,并且提高了安全性,使得有恶意推送和流氓软件的几率降低。

准备工作:参考大神博客https://www.cnblogs.com/ludashi/p/4093454.html

81、iOS本地推送与远程推送详解的更多相关文章

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

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

  2. iOS本地推送与远程推送详解

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

  3. iOS---iOS10适配iOS当前所有系统的远程推送

    一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出 ...

  4. EasyRTMP推送扩展支持HEVC(H265) RTMP推送之Metadata结构填写详解

    我们在<EasyNVR摄像机网页直播中,推流组件EasyRTMP推送RTMP扩展支持HEVC(H.265)的方案>中描述了关于EasyRTMP进行RTMP HEVC(H.265)推流的概括 ...

  5. CentOS6.5下VNC Server远程桌面配置详解

    参考文献: (总结)CentOS Linux下VNC Server远程桌面配置详解 远程桌面连接工具VNC——license Key 我的下载地址为 太平洋下载 VNC连接黑屏的问题 centos 6 ...

  6. appledoc导出iOS代码文档的使用和问题详解(干货篇)

    appledoc导出iOS代码文档的使用和问题详解(干货篇) 1. 简单说一下背景和自己感受 背景: 项目好像突然黄了,公司让详细写项目代码的注释并且导出文档,弄完之后就要封版. 说实话:听到这个消息 ...

  7. 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)

    李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...

  8. Linux实现利用SSH远程登录服务器详解

    Linux实现利用SSH远程登录服务器详解 http://www.111cn.net/sys/linux/55152.htm

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

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

随机推荐

  1. 两个对象的 hashCode()或equals相同,equals或hashCode不一定相同--《案例演示》

    两个对象的 hashCode()或equals相同,equals或hashCode不一定相同 1.两个对象的equals相同,hashCode不一定相同 在重写equals方法,未重写hashCode ...

  2. SQL Server扩展事件的使用ring_buffer target时“丢失”事件的原因分析以及ring_buffer target潜在的问题

    事情起因: 排查SQL Server上的死锁问题,一开始想到的就是扩展事件, 第一种方案,开profile守株待兔吧,显得太low了,至于profile的变种trace吧,垂垂老矣,也一直没怎么用过. ...

  3. ssl简介与openssl的使用

    SSL证书:  是数字证书的一种,类似于驾驶证.护照和营业执照的电子副本.因为配置在服务器上,也称为SSL服务器证书. ssl也是传输协议. 基于ssl协议开发的一款软件叫openssl linux系 ...

  4. cent os安装filebeat

    先贴一下官方文档https://www.elastic.co/guide/en/beats/filebeat/6.6/filebeat-installation.html 我本次使用rpm的方式安装, ...

  5. fiddler抓https包

    若手机端安装证书后还是无法抓取到https请求,请注意手机端证书开关是否开启: eg:ios 设置---通用---关于本机---证书信任设置:开启证书信任 若还是无法抓包,则可以进行一下操作: 给fi ...

  6. form表单的三个属性 action 、mothod 、 enctype。

    form_action: 表单数据提交到此页面 下面的表单拥有两个输入字段以及一个提交按钮,当提交表单时,表单数据会提交到名为 "form_action.asp" 的页面: < ...

  7. 阿里巴巴 Weex

    原文链接:https://blog.csdn.net/zz901214/article/details/79168707/ 分享嘉宾:侑夕 阿里巴巴高级前端工程师(上张帅哥的图镇楼,看完,更有动力学习 ...

  8. event 事件2

    4.事件类型 “DOM3级事件”规定了一下几类事件: 1)UI事件(用户界面事件),当用户与页面元素交互时触发 2)焦点事件,当元素获得或失去焦点时触发 3)鼠标事件,当用户通过鼠标在页面上执行操作时 ...

  9. python--第十九天总结(Django)

    1.静态资源导入 {#在顶部load 一个staticfiles#} {% load staticfiles %} {#在底部使用#} <script src='{% static " ...

  10. 20175314 《Java程序设计》第八周学习总结

    20175314 <Java程序设计>第八周学习总结 教材学习内容总结 安利一个非常实用的图片处理工具:图片工厂,它具有非常强大的图片批处理能力,比如加水印.降低画质.命名等,不仅如此它还 ...