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 {// ...}}
}

我们可以通过使用 INPersonINSendMessageIntent创建此信息将其添加到您的推送通知消息中

具体实现代码如下:

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+)相关推荐

  1. iOS 通信通知 Communication Notifications 的实现

    背景 看到群里有同学在咨询,推送通知如何自定义左侧的icon 部位,因为iOS 10之后有推出,通知扩展,所以大家知道可以通过Notification Extension 可以给通知添加媒体资源即图片 ...

  2. 通过iOS15 Communication Notifications实现自定义通知图标

    通过iOS15 Communication Notifications实现自定义通知图标 前言 原理 实现 MainTarget的配置 1.配置info.plist文件 2.配置Capability ...

  3. iOS 15查找我的有什么作用?

    苹果在iOS 13中将"查找我的朋友"和"查找我的iPhone"合并到一个名为"查找我的"应用程序中,用于定位你的设备并查看你朋友和家人的位 ...

  4. 华为诉争“鸿蒙HongMeng”商标再被驳回;比尔盖茨夫妇正式离婚;iOS 15“查找”新功能,关机也能用|极客头条...

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 孙胜 出品 | CSDN(ID:CSDNnews) ...

  5. WeTest云手机升级,支持iOS 15全新系统

    北京时间9月21日凌晨1点,苹果公司正式向全球用户推送了iOS 15正式版操作系统,此次系统更新带来了全新的FaceTime与更智能化的通知中心界面,并加入了实况文本.专注模式等实用功能.对各小程序例 ...

  6. 极客日报:华为诉争“鸿蒙HongMeng”商标再被驳回;比尔盖茨夫妇正式离婚;iOS 15“查找”新功能,关机也能用

    一分钟速览新闻点! 美团App内测短视频功能 华为诉争"鸿蒙HongMeng"商标再被驳回 陌陌宣布更名为「Hello」集团 美团宣布开启"2022校园招聘" ...

  7. 【极光笔记】iOS 15推送新特性初探

    前言 北京时间2021年6月8日凌晨1点,苹果召开了WWDC 21大会.在会上发布了新版的iOS 15系统,iOS的主题是Focus, connect, and explore. 有关注的同学应该发现 ...

  8. 苹果又魔改安卓? iOS 15 正式发布、可跨设备移动文件,这届 WWDC21 带来了什么?...

    作者 | 苏宓 出品 | CSDN(ID:CSDNnews) 还记得在 2007 年 iPhone 首次发布会上,乔布斯曾引用了 SmallTalk 之父.图灵奖获得者 Alan Kay 的一句话来分 ...

  9. 苹果iOS 15发布:关机也能定位,ASMR重度用户狂喜,这波库克又“去苹果化”了...

    梦晨 萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI 万众瞩目的苹果iOS 15正式版终于来了! 最受关注的更新,要属"实况文本",现在复制图中的文字就像复制文本一样简 ...

最新文章

  1. html5主要是针对哪方面行优化,前端知识点总结(HTML篇)
  2. docker容器互联实战
  3. 实现DFS之“农田灌溉”
  4. css实现快速抖动效果_web前端入门到实战:CSS实现照片堆叠效果
  5. 列出本机安装的所有硬件设备
  6. 动态网络表征学习在推荐领域的创新与实践
  7. Linux运行shell脚本出现出错,可能是环境编码不一致造成的。
  8. Kotlin基础(五)Kotlin的类型系统
  9. stm32跑马灯程序
  10. 自动计数报警器c语言程序,自动计数报警器.ppt
  11. PC端上必应词典与金山词霸的测评分析
  12. 7大需求分析方法与5大分析过程
  13. 【笔记总结】高中生物——【选一 Ⅱ】第二章 微生物的培养与应用
  14. html5水墨,web前端入门到实战:html5网页特效-水墨动画
  15. matlab 打开xls文件,matlab中读取excel的xls文件
  16. 电脑通过二维码打开手机链接
  17. JAVA POI获取excel单元格红色字体,淡蓝色前景色的内容
  18. 航空航天与国防行业乘客体验—了解如何交付个性化并实现盈利 | 达索系统百世慧®
  19. 关于时区您了解多少呢?在中国我们使用的是哪个时区?
  20. Python 语言及其应用 Chapter_3_Note_2 容器_列表_元组_字典_集合

热门文章

  1. 2021-06-07算术
  2. 英语基本语法(三)-代词
  3. c语言如何引入第三方库,在Rust中,如何从第三方库定义或导入C结构体?
  4. CDC中FillRect与FillSolidRect的区别。
  5. Android初级学习推荐书籍
  6. 基于B站王阿华的视频——为什么当下自媒体都在制造焦虑以及如何摆脱
  7. 定时清除项目中不需要的图片
  8. js 格式化间隔时间(如:2分钟前)
  9. 介绍一下 WMS WCS PLC 之间的关系 并附加代码
  10. POJ 3311--佛洛依德枚举