美文网首页
iOS 15 Notifications

iOS 15 Notifications

作者: 欧阳蓝缺 | 来源:发表于2021-10-21 00:22 被阅读0次

    通知摘要

    通知摘要是一项可选功能,允许用户停止接收特定应用程序的实时推送通知。相反,系统会存储为这些应用程序收到的通知,并在锁屏上的摘要中显示它们。系统可以在一天中的不同时刻显示这些摘要,具体取决于用户的偏好。

    iOS 不会自动将应用程序添加到通知摘要中。首次启用该功能时,用户需要从系统设置中手动添加:

    image

    打开通知摘要后,推送权限提示将提供两个选项来处理应用程序的通知:

    • Allow Immediate Notifications”:收到通知后立即显示。

    • Add to Scheduled Summary”:收到通知后稍后显示在通知摘要中。

    image

    请注意,iOS 不提供检测用户选择的哪种通知处理方式(立即通知与预定摘要)。

    新增 API

    专注模式

    iOS 15 的新专注模式是当前勿扰模式的改进和扩展。用户可以创建不同的“专注模式”来过滤他们在活动期间(如:工作、驾驶等)收到的通知。从系统设置中,用户可以创建“工作”焦点并将其设置在同事、家人和特定应用程序通知到达时立即通知。

    image

    专注模式激活时,其他联系人和应用程序的通知将仅显示在通知中心,如下所示:

    image

    相关 API

    新的通知中断级别

    除了新的通知摘要和专注模式之外,iOS 15 还为推送通知引入了两个新的中断级别:passivetime-sensitive

    总共有四个不同的中断级别:

    • Passive 被动:对不需要立即关注的通知使用被动模式(如:营销活动等)。被动通知不会触发声音、振动和亮屏。

    • Active 活动:这是默认的中断级别(如:新闻等)。

    • Time-Sensitive 时间敏感:对需要立即关注的通知(如:帐户安全问题、快递送达等)使用时间敏感中断级别。该中断级别不要用于发送营销通知,因为这些通知可能会突破系统控制(通知摘要和专注模式)。

    • Critical 严重:严重中断级别用于需要立即关注的非常重要的通知(如:恶劣天气等)。这种使用必须由 Apple 明确允许并具有特殊权利。

    image

    请注意,时间敏感严重中断级别都可以突破通知摘要任何专注模式。iOS 将显示刚刚收到的通知:

    image

    如果 App 的时间敏感通知不经常交互,iOS 会从锁定屏幕提示用户,让用户为 App 禁用时间敏感的通知。用户也可以从系统设置中禁用:

    image

    发送时间敏感的通知

    先决条件

    为了使用时间敏感通知,App 需要将“时间敏感通知”功能添加到 Xcode 项目中。

    image

    设置推送通知数据

    时间敏感的中断级别可以使用“interruption-level” payload key:

    {"aps":{"interruption-level":"time-sensitive"}}
    
    

    新增 API

    通知操作图标

    通知操作现在可以包含图标以更好的表达相关操作。这些图标可以是 SFSymbol 系统图像,也可以是 App 提供的自定义图像。为了添加图标,Apple 提供了新的 API UNNotificationActionIcon 对象。Action Icon 对象可以使用系统或模板图像名称进行初始化,然后使用包含 icon 参数的新初始化方法添加到相应的 UNNotificationAction 中。您不需要在名称中指定文件扩展名或大小修饰符,因为会根据系统和可用图像资源自动检索正确的大小。

    image image

    通讯通知

    Apple 添加了将应用程序的通知区分为通信通知的功能。这些通知现在将包含发送它们的联系人的图像或头像,并且可以与 SiriKit 集成,以便 Siri 可以根据常用联系人智能地为通信操作提供快捷方式和建议。例如,当用户为焦点模式设置允许的联系人或从您的应用拨打电话时。 Siri 将根据您的应用程序提供的意图数据智能地推荐联系人。

    要使用通信通知,应用程序需要在 Xcode 中向其应用程序添加 Communication Notifications 功能,并使用实现了 UNNotificationContentProviding 协议的 Intent 对象更新 App Notification Service Extension 的通知内容。目前两个可用的实现是 INSendMessageIntentINStartCallIntent

    image

    APNs 实现通讯通知

    项目中添加 Notification Service Extension,将以下 key value 添加到 Notification Service Extension 的 Info.plist 中。

    image

    NotificationService.didReceive 中编写代码向通知对象添加附加信息。(每次 Apple APNs 在通知用户前,都会调用此方法)

    import UserNotifications
    import Intents
    import UIKit
    class NotificationService: UNNotificationServiceExtension {
    
        var contentHandler: ((UNNotificationContent) -> Void)?
        var bestAttemptContent: UNMutableNotificationContent?
    
        override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
            if let bestAttemptContent = bestAttemptContent {
                // ...
            }
        }
    }
    
    

    需要使用 INPerson 装载发送者信息,这些信息可以通过 APNs 通知传给 App。如:

    {
        "aps": {
            "alert": {
                "body": "Hello world! This is a test message.",
                "title": "@Neko"
            },
        },
        "sender_id": "1",
        "sender_name": "NekoNeko",
        "sender_image_url": "https://xxxx.com/xxx.jpg",
        "sender_nickname": "@Neko",
        "sender_email": "Neko@Neko.Neko",
        "chat_session_id": "chat_1"
    } 
    
    

    然后,可以通过使用 INPersonINSendMessageIntent 将发送者信息添加到推送通知中。

    class NotificationService: UNNotificationServiceExtension {
    
        var contentHandler: ((UNNotificationContent) -> Void)?
        var bestAttemptContent: UNMutableNotificationContent?
    
        override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
            self.contentHandler = contentHandler
            bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
    
            if let bestAttemptContent = bestAttemptContent {
                // Modify the notification content here...
                bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
    
                /* Use the custom information included in this notification from the chat server to retrive the chat participant's information. - This is the information of the sender of the message. - Providing a user's accruate name helps the iOS system match this user with a contact in the system contact app. */
                if let senderAccountID = bestAttemptContent.userInfo["sender_id"] as? String,
                   let senderName = bestAttemptContent.userInfo["sender_name"] as? String,
                   let senderImageURLString = bestAttemptContent.userInfo["sender_image_url"] as? String,
                   let senderImageURL = URL(string: senderImageURLString),
                   let senderDisplayName = bestAttemptContent.userInfo["sender_nickname"] as? String,
                   let senderEmailAddr = bestAttemptContent.userInfo["sender_email"] as? String,
                   let chatSessionID = bestAttemptContent.userInfo["chat_session_id"] as? String
                {
    
                    // You can also use the sender's phone number to initialize the `INPersonHandle` object. This will help the iOS system to match this sender with a contact.
                    // TODO: - Here you need to download the image data from the URL. In this demo, we are using a system image instead.
                    let messageSender = INPerson(
                        // email or phone number
                        personHandle: INPersonHandle(value: senderEmailAddr, type: .emailAddress),
                        nameComponents: try? PersonNameComponents(senderName),
                        displayName: senderDisplayName,
                        image: INImage(imageData: UIImage(systemName: "applelogo")!.pngData()!),
                        contactIdentifier: nil,
                        customIdentifier: senderAccountID,
                        isMe: false,
                        suggestionType: .instantMessageAddress
                    )
    
                    let intent = INSendMessageIntent(recipients: nil,
                                                     outgoingMessageType: .outgoingMessageText,
                                                     content: bestAttemptContent.body,
                                                     speakableGroupName: INSpeakableString(spokenPhrase: senderDisplayName),
                                                     conversationIdentifier: chatSessionID,
                                                     serviceName: nil,
                                                     sender: messageSender,
                                                     attachments: nil)
    
                    let interaction = INInteraction(intent: intent, response: nil)
                    interaction.direction = .incoming
                    interaction.donate(completion: nil)
                    do {
                        let messageContent = try request.content.updating(from: intent)
                        contentHandler(messageContent)
                    } catch {
                        print(error.localizedDescription)
                    }
    
                }
    
                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)
            }
        }
    
    }
    
    

    相关资料

    相关文章

      网友评论

          本文标题:iOS 15 Notifications

          本文链接:https://www.haomeiwen.com/subject/mwoxaltx.html