如何在iOS中创建类似WhatsApp的通知布局(用用户图标替代应用图标)
iOS 实现自定义推送图标(替换应用图标为用户头像)
要实现类似WhatsApp的推送通知效果,把默认应用图标换成用户头像,需要结合苹果的通知服务扩展和推送Payload配置来实现,具体步骤如下:
1. 添加通知服务扩展(Notification Service Extension)
- 在Xcode中,选择你的项目 → 点击"+"添加Target → 选择"Notification Service Extension",按照向导完成创建。
- 这个扩展的作用是在推送通知到达设备后、显示前,修改通知内容,比如添加自定义附件(用户头像)。
2. 配置推送Payload
推送时需要在Payload中包含用户头像的URL,并且指定mutable-content: 1,告诉系统需要调用通知服务扩展处理:
{ "aps": { "alert": { "title": "张三", "body": "今晚一起吃饭?" }, "mutable-content": 1 }, "userAvatarUrl": "https://example.com/user-avatar.jpg" // 替换为实际用户头像URL }
3. 在通知服务扩展中处理头像附件
在NotificationService.swift中,下载用户头像并添加为通知附件:
import UserNotifications 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) guard let content = bestAttemptContent, let avatarUrlString = content.userInfo["userAvatarUrl"] as? String, let avatarUrl = URL(string: avatarUrlString) else { contentHandler(request.content) return } // 下载头像图片 URLSession.shared.downloadTask(with: avatarUrl) { [weak self] tempUrl, response, error in guard let self = self, let tempUrl = tempUrl, error == nil else { contentHandler(request.content) return } // 将临时文件移动到可访问的目录 let fileManager = FileManager.default let ext = avatarUrl.pathExtension let fileName = UUID().uuidString + "." + ext let destUrl = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "你的AppGroupID")?.appendingPathComponent(fileName) do { if fileManager.fileExists(atPath: destUrl!.path) { try fileManager.removeItem(at: destUrl!) } try fileManager.moveItem(at: tempUrl, to: destUrl!) // 创建通知附件 let attachment = try UNNotificationAttachment(identifier: "userAvatar", url: destUrl!, options: nil) content.attachments = [attachment] // 系统会自动将附件作为通知的图标展示 contentHandler(content) } catch { contentHandler(request.content) } }.resume() } override func serviceExtensionTimeWillExpire() { // 超时处理,返回原始内容 if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } }
注意:需要配置App Group,确保扩展和主App能共享文件目录,否则无法访问下载的头像文件。
4. 可选:自定义通知布局(Notification Content Extension)
如果需要更复杂的自定义消息样式,可以添加Notification Content Extension:
- 添加Target选择"Notification Content Extension",创建后在
NotificationViewController.swift中自定义UI布局,比如添加头像ImageView、消息文本等。 - 在Payload中指定
category字段,关联到自定义通知类别,系统会调用对应的Content Extension展示自定义UI。
关键注意事项
- 推送的头像URL必须是HTTPS协议,苹果不允许HTTP资源作为通知附件。
- 通知服务扩展的处理时间有限(约30秒),要确保头像下载速度足够快,否则会超时使用原始通知内容。
- 测试时需要用真实设备,模拟器对通知扩展的支持有限。
内容的提问来源于stack exchange,提问作者pw2
相关产品推荐
相关产品推荐

