Swift中如何为Notification Service Extension的Info.plist添加Communication Notification功能
在Swift中为Notification Service Extension配置Communication Notification功能
一、配置Notification Service Extension的Info.plist
打开你的Notification Service Extension目标下的Info.plist,按以下步骤添加/修改配置:
- 找到(或添加)
NSExtension字典,确保其中的NSExtensionPointIdentifier值为com.apple.usernotifications.service(这是Notification Service Extension的默认标识,一般已存在)。 - 在
NSExtension下添加NSExtensionAttributes字典,在其中添加以下键值对:UNNotificationExtensionCategory:字符串类型,设置为你的通信通知分类标识,例如$(PRODUCT_BUNDLE_IDENTIFIER).communication(后续推送通知需匹配此分类才能触发Extension处理)。UNNotificationExtensionDefaultContentHidden:布尔类型,设置为YES,表示用自定义的通信内容替换系统默认通知内容。UNNotificationExtensionInitialContentSizeRatio:数值类型,设置为0.75(可选,调整通知的初始高度比例)。
- 在Info.plist根层级添加
NSUserActivityTypes数组,添加字符串元素INSendMessageIntent,这是系统识别通信Intent所需的配置。
二、修正并优化NotificationService代码
你提供的代码存在几处问题,以下是修正后的完整实现:
import UserNotifications import Intents class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) // 创建发送方的姓名组件(修复原代码未定义的personNameComponents) let personNameComponents = PersonNameComponents(givenName: "Sender", familyName: "Name") // 确保图片资源已添加到Notification Service Extension的Target中 guard let avatar = INImage(named: "Cover") else { contentHandler(request.content) return } // 定义发送方和当前用户(接收方)的INPerson实例 let senderPerson = INPerson( personHandle: INPersonHandle(value: "1233211234", type: .unknown), nameComponents: personNameComponents, displayName: "Sender Name", image: avatar, contactIdentifier: nil, customIdentifier: nil, isMe: false, suggestionType: .none ) let mePerson = INPerson( personHandle: INPersonHandle(value: "1233211232", type: .unknown), nameComponents: nil, displayName: "Me", image: nil, contactIdentifier: nil, customIdentifier: nil, isMe: true, suggestionType: .none ) // 创建消息Intent(incoming消息的sender是发送方,recipients是当前用户) let incomingMessagingIntent = INSendMessageIntent( recipients: [mePerson], outgoingMessageType: .outgoingMessageText, content: "Test Dude", speakableGroupName: nil, conversationIdentifier: "uid", serviceName: "caset", sender: senderPerson, attachments: [] ) incomingMessagingIntent.setImage(avatar, forParameterNamed: \.sender) // 更新通知内容为通信样式 do { let newContent = try request.content.updating(from: incomingMessagingIntent) contentHandler(newContent) } catch { print("更新通信通知失败: \(error.localizedDescription)") // 失败时回退到原始通知内容 if let bestAttemptContent = self.bestAttemptContent { contentHandler(bestAttemptContent) } else { contentHandler(request.content) } } } override func serviceExtensionTimeWillExpire() { // 超时处理,确保调用contentHandler if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } }
代码修正说明:
- 补充了
personNameComponents的定义,解决原代码未初始化导致的编译错误。 - 添加了图片资源的空值判断,避免因资源缺失导致崩溃。
- 完善了错误处理逻辑,当更新通信通知失败时回退到原始内容,同时实现
serviceExtensionTimeWillExpire方法处理超时场景。 - 给
mePerson补充了displayName,提升通知显示的完整性。
额外注意事项
- 确保推送通知的
category字段与Info.plist中配置的UNNotificationExtensionCategory一致,否则Extension不会触发。 - 将需要使用的图片资源(如"Cover")添加到Notification Service Extension的Target中,否则会找不到资源。
- 通信通知功能需要iOS 12及以上系统支持。
内容的提问来源于stack exchange,提问作者Akash Raja
相关产品推荐
相关产品推荐

