
正文
包含ios通知开发的词条
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
iOS本地通知的实现
通知的原理,在这里就不做过多的解释了,不懂的朋友可以自行Google
这里我们主要说下本地推送。
目前来说本地通知主要分为iOS 10 及 iOS 10以下两种不同方式
在iOS 10上 我们可以定义对于推送的各种快捷操作,那么我们的如何实现操作方法呢?
答案就是代理,苹果官方的API几乎都是如此!
首先 遵循 代理 UNUserNotificationCenterDelegate
实现代理方法,在实际开发中,注意对应的 categoryid
iOS 10上 还有很多操作性的API,修改通知的内容或移除通知等
上篇:iOS推送权限开发判断
下篇:iOS通知消息的处理
如有瑕疵之处,望大家不吝指教
相关问答
Q1: iOS 重要通知的设置(critical-alerts)
授予权限还是有些要求的,这些为苹果考虑到用可能到此功能的分类:Healthcare(医疗保健)、Public Safety(公共安全)、Personal Safety and Security(个人安全)、Enterprise In-house(企业内部)、Other(其他分类也可描述使用场景)
需要填写:
1.app类型
2.描述你的app
3.发送紧急通知的消息类型
4.紧急通知的频率
5.解释为什么需要用到紧急通知及功能设计过程
Request a Critical Alert Notifications Entitlement
等待些许时日后会收到申请成功的邮件
然后我们登录自己的 开发者账号 创建开发或者发布的provisioning profile证书最后就多了一个这样的选项
critical alerts 只支持iOS12.0以上的系统,在设置UNUserNotificationCenter中增加criticalAlert
然后在 app.entitlements 中增加key com.apple.developer.usernotifications.critical-alerts 类型为boolean 并将值设为 1
使用我们刚刚创建的provisioning profile证书运行demo,可看见app中多了
参考:
Q2: iOS 必知必会 - APNs篇
导语:
由于移动设备内存、CPU、电量的局限性,iOS 不允许 APP 的进程常驻后台(事实上可以申请后台运行一段时间,最长约 10 分钟),这样当用户主动杀掉 APP,或者 APP 进入后台超过约定时长时,就意味着该 APP 进程的结束。这在很大程度上保障了前台 APP 的流畅性,也延长了手机的使用时长,获得了较好的用户体验。但是这也意味着,服务器无法主动和用户交互(如推送实时消息等)。为了解决这个限制,苹果推出了 APNs,允许设备和服务器分别与苹果的推送通知服务器保持长连接状态。
iOS 的通知分为本地通知和远程通知。本地通知是由本地应用触发的,一般是基于时间的一种通知形式,如闹钟、待办事件等的提醒。远程通知是由开发商通过自己的服务器推送的一种通知形式,而 APNs 就是远程通知功能的核心。
关于远程推送,记住以下两点就够了:
这里就很清楚了,其实 APNs 的本质就是 服务器和客户端之间的中介 。当服务器需要给客户端推送消息时,先将消息发送给苹果服务器,再由苹果服务器找到对应设备推送下去。
那为什么还要走中介,不直接发送呢?因为这样做一个设备(即所有 APP )只需要和苹果的服务器建立一条长连接,而不需要每个 APP 都和服务器建立一条长连接。
可能有些人还是不太明白 APNs 的意义,觉得也只是将多个长连接变成了统一的一个长连接而已,有必要那么做吗?
很有必要!
我们来看下 Android 的推送现状就明白了。
Android 事实上也有类似于 APNs 的一套用于推送的服务,简称 GCM,即 Google Cloud Messaging。但由于 GCM 需要谷歌服务器的支持,在国内由于「墙」的原因基本不能使用。这下就热闹了,国内出现了一大堆第三方推送服务商,如华为推送、小米推送、极光推送等。APP 通过集成这些推送服务来实现推送功能,而这些推送服务为了保持自己的长连接不被杀死,采用了各种保活、唤醒手段,这也是 Android 手机使用不流畅的真凶。之前也有看到「 工信部要求国内安卓统一消息推送标准 」的新闻,工信部都这么重视,可见统一推送的意义非凡。
想要了解具体区别,可以参考这篇文章 「 国内 90%以上的 iOS 开发者,对 APNs 的认识都是错的 」。
不言而喻,当然是尽早升级 HTTP/2 协议了。
参考:
(完)
Q3: iOS开发 - NSNotification原理理解
NSNotification是iOS中一个调度消息通知的类,采用单例设计模式,在开发中实现传值、回调等。在iOS中,NSNotification是使用观察者模式来实现用于跨层传递消息。
NSNotification包含了一些用于向其他对象发送通知的必要信息,包括名称、对象和可选字典,并由NSNotificationCenter或NSDistributedNotificationCenter的实例进行发送。name是标识通知的标记、object是保存发送通知的对象、userinfo存储其他相关对象。 这里主要注意的是:NSNotification对象是不可变的。
可以使用 notificationWithName:object: 或 notificationWithName:object:userInfo: 创建通知对象。但实际开发中,一般是直接使用NSNotificationCenter调用 postNotificationName:object: 或 postNotificationName:object:userInfo: ,这两个类方法会在内部直接创建NSNotification对象,并发出通知。
从官网文档可知,NSNotification是不能直接实例化的,如果用init方法进行实例化时,会引发异常。还有需要注意的是如果我们自己去实现构造方法时,不能在super上调用init方法。
NSNotificationCenter提供了一套机制来发送通知,每个运行中的应用程序都有一个defaultCenter通知中心,我们可以创建新的通知中心来组织特定上下文中的通信。 NSNotificationCenter暴露给外部的字段只有一个defaultCenter,并且该字段是只读的,暴露出来的方法分为三种:添加、移除通知观察者和发出通知。详细如下表所示:
postNotificationName:object:
postNotificationName:object:userInfo: |
相关说明:
简单理解为:通知中心的缓冲区。尽管通知中心已经分发通知,但放置到队列中的通知可能会延迟,直到runloop结束或者runloop空闲时才发送。如果有多个相同的通知,NSNotificationQueue会将其进行合并,以便在发布多个通知的情况下只发送一个通知。
通知队列按照先进先出(FIFO)的顺序维护通知。当一个通知移动到队列的前面时,队列将它发送到通知中心,然后再将通知分派给所有注册为观察者的对象。每个线程都有一个默认的通知队列,该队列与流程的默认通知中心相关联。我们也可以创建自己的通知队列。
和NSNotificationCenter一样,NSNotificationQueue也只暴露了一个字段:defaultQueue,返回当前线程的默认通知队列。方法分为:创建通知队列和管理通知。详细说明如下表所示:
dequeueNotificationsMatching:coalesceMask:
enqueueNotification:postingStyle:coalesceMask:forModes: |
方法相关说明:
在上面的方法中,需要注意的2个常量,相关说明如下:
NSNotificationCenter定义了两个Table,同时为了封装观察者信息,也定义了Observation保存观察者信息。他们的结构体可以简化如下所示:
在NSNotificationCenter内部一共保存了两张表,一张用于保存添加观察者的时候传入的NotificationName的情况;一张用于保存添加观察者的时候没有传入NotificationCenter的情况,详细分析如下:
在Named Table中,NotificationName作为表的key,因为我们在注册观察者的时候是可以传入一个object参数用于只监听该对象发出的通知,并且一个通知可以添加多个观察者,所以还需要一张表用来保存object和observe的对应关系。这张表的key、value分别是以object为key,observe为value。所以对于Named Table,最终的结构为:
Named Table
特别说明:在实际开发中,我们经常将object参数传nil,这个时候系统会根据nil自动产生一个key。相当于这个key对应的value(链表)保存的就是对于当前NotificationName没有传入object的所有观察者。当NotificationName被发送时,在链表中的观察者都会收到通知。
UNamed Table结构比Named Table简单得多。因为没有NotificationName作为key。这里直接就以object为key,比Named Table少了一层Table嵌套。
UnNamed Table
如果在注册观察者时没有传入NotificationName,同时没有传入object,所有的系统通知都会发送到注册的对象里。
首先在初始化NSNotificationCenter时会创建一个对象,这个对象里面保存了Named Table、UNamed Table和其他信息。
在没有传入NotificationName的情况和上面的过程类似,只不过是直接根据object去对应的链表而已。如果既没有传入NotificationName,也没有传入object,则这个观察者会添加到wildcard链表中。
发送通知一般是调用 postNotificationName:object:userInfo: 方法来实现。该方法内部会实例化一个NSNotification来保存传入的各种参数,包括name、object和userinfo。
发送通知的流程总体来说就是根据NotificationName查找到对应的Observer链表,然后遍历整个链表,给每个Observer结点中保存的对象及SEL,来向对象发送消息。具体流程如下:
这个方式也就能说明,发送通知的线程和接收通知的线程都是同一个线程。
NSNotification和线程同步之间是什么关系呢?先看下官方文档的说明:
翻译过来意思为:
更多关于NSNotification与线程之间的关系,请阅读下面的文章: iOS开发 - NSNotification和线程相关
总的来说,NSNotification的三个相关类的作用,可以用下图进行归纳总结。
总结
Q4: iOS开发将通知栏字体设置为白色
很多情况下通知栏字体是黑色的,看起来不怎么协调。
在TARGETS Info中添加以下两个key:
1.View controller-base status bar appearance,值设置为NO
2.Status bar style,值设置为Light Content
Q5: iOS 通知的3种使用方式
方法一 不传递参数, 最常用的一种
// 发送通知
-(void)btn1Click
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"noti1" object:nil];
}
//监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(noti1) name:@"noti1" object:nil];
//调用方法
-(void)noti1{
NSLog(@"接收 不带参数的消息”);
}
方法二 使用object 传递消息
-(void)btn2Click:(UIButton *)btn
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"noti2" object:[NSString stringWithFormat:@"%@",btn.titleLabel.text]];
}
//监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(noti2:) name:@"noti2" object:nil];
//掉用方法
-(void)noti2:(NSNotification *)noti
{
//使用object处理消息
NSString *info = [noti object];
NSLog(@"接收 object传递的消息:%@",info);
}
方法三 使用userInfo 传递消息
1。通知页面
2.接受处理页面
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeBgColor:) name:@"changeBgColor" object:nil];
-(void)dealloc{
NSLog(@"移除了所有的通知");
[[NSNotificationCenter defaultCenter] removeObserver:self];
//第二种方法.这里可以移除该控制器下名称为tongzhi的通知
//移除名称为tongzhi的那个通知
NSLog(@"移除了名称为tongzhi的通知");
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"tongzhi" object:nil];






