一、简介

分为本地推送和远程推送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. take it easy

    昨天魏辉在群里说,觉得自己以前很多事情做的不对,以前是个傻瓜,我说我也是这么觉得的.为什么这么说呢?因为我真的觉得以前的自己就是个SB.人的成长可能就是这样的吧,小时候的一些事情,或者是原生家庭的环境 ...

  2. python并发编程基础之守护进程、队列、锁

    并发编程2 1.守护进程 什么是守护进程? 表示进程A守护进程B,当被守护进程B结束后,进程A也就结束. from multiprocessing import Process import time ...

  3. 关于安装angular-cli环境报错的问题

    最近使用angular2,需要安装angular cli环境 然后使用官网教程命令执行 npm install -g @angular/cli 出现异常如下图: 说找不到python2,我已经安装了p ...

  4. WordCount编码实现及单元测试(第二次作业)

    项目码云地址:https://gitee.com/zhujunlin/wc.git 一.题目思路 ========== 阅读完题目要求之后我很懵,因为之前从未使用过博客园和码云工具,对编程的目标需求也 ...

  5. Fragment传参

    1. 封装基类 /** * Created by chenhaibin * Time 18/1/20 * Email chenhaibin415@163.com * Description:封装代码的 ...

  6. FileProvider的使用及应用更新时提示:解析包出错、失败等问题

    Android 7.0以上的版本更新采用系统自带的DownloadManager更新 DOWNLOADPATH ="/download/" https://www.jianshu. ...

  7. php 计算坐标点方圆周围多少米的坐标算法

    //地球半径 6371千米 const EARTH_ROUNT = 6371; /** * @param $distance 方圆多少千米 默认500米 */ private function _ge ...

  8. jmeter入门案例(二)

    jmeter入门简介(一)下载及元件介绍https://www.cnblogs.com/wish5714/p/9714930.html jmeter典型的http请求示例 业务场景 银行卡收单交易,模 ...

  9. Leetcode中sort排序遇到的一些问题

    class Solution { public: static bool cmp(vector<int>a,vector<int>b) { ]-a[]<b[]-b[]; ...

  10. 记录下本地修改php版本的过程, 本地PHP目录位置,PHP-FPM目录位置

    由于我在Cellar下安装了多个PHP版本,所以这里记录下如何修改本地的PHP版本 cd /usr/local/bin cp php71 php cp php71-fpm php-fpm vscode ...