通信通知 Communication Notifications 的实现 (iOS 15+)
WWDC 2021 苹果在 iOS 15 系统中对通知做了很多改变, 让通知更加个性化.
这里只有讨论通信通知 Communication Notifications
, 苹果自带的很多应用, 以及第三方App 飞书, 都使用了这个通知功能。
通信通知 Communication Notifications 简介
iOS 15系统后, Apple 添加了通信通知的功能。这些通知将包含发送它们的联系人的头像,并且可以与 SiriKit 集成,以便 Siri 可以智能地根据常用联系人提供通信操作的快捷方式和建议。
图例:
通信通 Communication Notifications 具体实现:
要使用通信通知,App 需要在 Xcode 中将通信通知功能添加到其应用程序,并在应用程序通知服务扩展中实现 UNNotificationContentProviding
协议。
1.首先将以下键值添加到主应用程序 Info.plist 文件中
NSUserActivityTypes (Array)- INStartCallIntent- INSendMessageIntent
具体位置如图所示:
2.在 Xcode
-> Capabilities
中添加 Communication Notifications
功能
如图所示:
3.添加 Notification Service Extension
扩展
大多数社交媒体通知都是从服务器发送到 Apple 的 APN 服务器,然后再发送到设备。
我们需要使用通知服务扩展, 该扩展用于处理通知,然后将它们显示在屏幕上。
首先,将扩展Notification Service Extension
添加到项目中
然后将以下键和值添加到 Notification Service Extension
扩展 Info.plist
中
4.在 Notification Service Extension
扩展下 NotificationService
文件中, 重写 didReceive
方法
Apple APN 服务器每次在通知出现在用户屏幕上之前,都会调用此方法
初始代码如下:
import UIKit
import Intents
import UserNotificationsclass NotificationService: UNNotificationServiceExtension {var contentHandler: ((UNNotificationContent) -> Void)?var bestAttemptContent: UNMutableNotificationContent?override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {if let bestAttemptContent = bestAttemptContent {// ...}}
}
我们可以通过使用 INPerson
或INSendMessageIntent
创建此信息将其添加到您的推送通知消息中
具体实现代码如下:
class NotificationService: UNNotificationServiceExtension {var contentHandler: ((UNNotificationContent) -> Void)?var bestAttemptContent: UNMutableNotificationContent?override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {self.contentHandler = contentHandlerbestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)if let bestAttemptContent = bestAttemptContent {// Modify the notification content here...// 获取通信消息if let senderAccountID = bestAttemptContent.userInfo["sender_id"] as? String,// 发送者名称let senderName = bestAttemptContent.userInfo["sender_name"] as? String,// 发送者图像url地址let senderImageURLString = bestAttemptContent.userInfo["sender_image_url"] as? String,// 发送者昵称let senderDisplayName = bestAttemptContent.userInfo["sender_nickname"] as? String,// 通信idlet chatSessionID = bestAttemptContent.userInfo["chat-session_id"] as? String{// Here you need to download the image data from the URL.self.getMediaAttachment(for: senderImageURLString) { image inguard let groupIcon = image else {contentHandler(bestAttemptContent)return}let avatar = INImage(imageData: groupIcon.pngData()!)// 消息发送方let messageSender = INPerson(personHandle: INPersonHandle(value: nil, type: .unknown),nameComponents: try? PersonNameComponents(senderName),displayName: senderDisplayName,image: avatar,contactIdentifier: nil,customIdentifier: senderAccountID,isMe: false,suggestionType: .none)// 消息接收方let mePerson = INPerson(personHandle: INPersonHandle(value: "", type: .unknown),nameComponents: nil,displayName: nil,image: nil,contactIdentifier: nil,customIdentifier: nil,isMe: true,suggestionType: .none)let intent = INSendMessageIntent(recipients: [mePerson, messageSender],outgoingMessageType: .outgoingMessageText,content: bestAttemptContent.body,speakableGroupName: INSpeakableString(spokenPhrase: senderDisplayName),conversationIdentifier: chatSessionID,serviceName: nil,sender: messageSender,attachments: nil)intent.setImage(avatar, forParameterNamed: \.speakableGroupName)let interaction = INInteraction(intent: intent, response: nil)interaction.direction = .incominginteraction.donate(completion: nil)do {let messageContent = try request.content.updating(from: intent)contentHandler(messageContent)} catch {print(error.localizedDescription)contentHandler(bestAttemptContent)}}}contentHandler(bestAttemptContent)}}override func serviceExtensionTimeWillExpire() {// Called just before the extension will be terminated by the system.// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {contentHandler(bestAttemptContent)}}
}
使用到的工具扩展, 包含图片下载和本地保存
extension NotificationService {// 保存图片到本地 并返回 本地 url 地址private func saveImageAttachment(image: UIImage, forIdentifier identifier: String) -> URL? {// 1 获取临时文件夹let tempDirectory = URL(fileURLWithPath: NSTemporaryDirectory())// 2 拼接文件路径let directoryPath = tempDirectory.appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString,isDirectory: true)do {// 3 如果文件夹不存在 创建文件夹try FileManager.default.createDirectory(at: directoryPath,withIntermediateDirectories: true,attributes: nil)// 4 文件地址URLlet fileURL = directoryPath.appendingPathComponent(identifier)// 5 文件二进制guard let imageData = image.pngData() else {return nil}// 6 保存二进制文档到本地路径try imageData.write(to: fileURL)return fileURL} catch {return nil}}// 通过本地 url 地址 获取图片资源private func getMediaAttachment(for urlString: String, completion: @escaping (UIImage?) -> Void) {// 1guard let url = URL(string: urlString) else {completion(nil)return}// 2 通过远程图片URL下载图片downloadImage(forURL: url) { result in// 3guard let image = try? result.get() else {completion(nil)return}// 4completion(image)}}// 通过远程图片url地址 下载图片文件public enum DownloadError: Error {case emptyDatacase invalidImage}private func downloadImage(forURL url: URL, completion: @escaping (Result<UIImage, Error>) -> Void) {let task = URLSession.shared.dataTask(with: url) { data, response, error inif let error = error {completion(.failure(error))return}guard let data = data else {completion(.failure(DownloadError.emptyData))return}guard let image = UIImage(data: data) else {completion(.failure(DownloadError.invalidImage))return}completion(.success(image))}task.resume()}
}
额外补充: 通知 Notifications 实现附件图片展示
在回调 bestAttemptContent 之前, 给它设置 attachments
属性即可
@available(iOS 10.0, *)
open class UNMutableNotificationContent : UNNotificationContent {/// ...// Optional array of attachments.open var attachments: [UNNotificationAttachment]/// ...
}
核心代码如下:
// 创建图片附件
let imageAttachment = try? UNNotificationAttachment(identifier: "image",url: "图片本地路径, 和上面设置 Avatar 地址一样",options: nil)// 赋值给 bestAttemptContent
if let imageAttachment = imageAttachment {bestAttemptContent.attachments = [imageAttachment]
}// 回调出去
contentHandler(bestAttemptContent)
通信通知 Communication Notifications 的实现 (iOS 15+)相关推荐
- iOS 通信通知 Communication Notifications 的实现
背景 看到群里有同学在咨询,推送通知如何自定义左侧的icon 部位,因为iOS 10之后有推出,通知扩展,所以大家知道可以通过Notification Extension 可以给通知添加媒体资源即图片 ...
- 通过iOS15 Communication Notifications实现自定义通知图标
通过iOS15 Communication Notifications实现自定义通知图标 前言 原理 实现 MainTarget的配置 1.配置info.plist文件 2.配置Capability ...
- iOS 15查找我的有什么作用?
苹果在iOS 13中将"查找我的朋友"和"查找我的iPhone"合并到一个名为"查找我的"应用程序中,用于定位你的设备并查看你朋友和家人的位 ...
- 华为诉争“鸿蒙HongMeng”商标再被驳回;比尔盖茨夫妇正式离婚;iOS 15“查找”新功能,关机也能用|极客头条...
「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 孙胜 出品 | CSDN(ID:CSDNnews) ...
- WeTest云手机升级,支持iOS 15全新系统
北京时间9月21日凌晨1点,苹果公司正式向全球用户推送了iOS 15正式版操作系统,此次系统更新带来了全新的FaceTime与更智能化的通知中心界面,并加入了实况文本.专注模式等实用功能.对各小程序例 ...
- 极客日报:华为诉争“鸿蒙HongMeng”商标再被驳回;比尔盖茨夫妇正式离婚;iOS 15“查找”新功能,关机也能用
一分钟速览新闻点! 美团App内测短视频功能 华为诉争"鸿蒙HongMeng"商标再被驳回 陌陌宣布更名为「Hello」集团 美团宣布开启"2022校园招聘" ...
- 【极光笔记】iOS 15推送新特性初探
前言 北京时间2021年6月8日凌晨1点,苹果召开了WWDC 21大会.在会上发布了新版的iOS 15系统,iOS的主题是Focus, connect, and explore. 有关注的同学应该发现 ...
- 苹果又魔改安卓? iOS 15 正式发布、可跨设备移动文件,这届 WWDC21 带来了什么?...
作者 | 苏宓 出品 | CSDN(ID:CSDNnews) 还记得在 2007 年 iPhone 首次发布会上,乔布斯曾引用了 SmallTalk 之父.图灵奖获得者 Alan Kay 的一句话来分 ...
- 苹果iOS 15发布:关机也能定位,ASMR重度用户狂喜,这波库克又“去苹果化”了...
梦晨 萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI 万众瞩目的苹果iOS 15正式版终于来了! 最受关注的更新,要属"实况文本",现在复制图中的文字就像复制文本一样简 ...
最新文章
- html5主要是针对哪方面行优化,前端知识点总结(HTML篇)
- docker容器互联实战
- 实现DFS之“农田灌溉”
- css实现快速抖动效果_web前端入门到实战:CSS实现照片堆叠效果
- 列出本机安装的所有硬件设备
- 动态网络表征学习在推荐领域的创新与实践
- Linux运行shell脚本出现出错,可能是环境编码不一致造成的。
- Kotlin基础(五)Kotlin的类型系统
- stm32跑马灯程序
- 自动计数报警器c语言程序,自动计数报警器.ppt
- PC端上必应词典与金山词霸的测评分析
- 7大需求分析方法与5大分析过程
- 【笔记总结】高中生物——【选一 Ⅱ】第二章 微生物的培养与应用
- html5水墨,web前端入门到实战:html5网页特效-水墨动画
- matlab 打开xls文件,matlab中读取excel的xls文件
- 电脑通过二维码打开手机链接
- JAVA POI获取excel单元格红色字体,淡蓝色前景色的内容
- 航空航天与国防行业乘客体验—了解如何交付个性化并实现盈利 | 达索系统百世慧®
- 关于时区您了解多少呢?在中国我们使用的是哪个时区?
- Python 语言及其应用 Chapter_3_Note_2 容器_列表_元组_字典_集合