NotificationContentExtension加载UNNotificationAttachment时UIImage显示不全如何处理
问题根因
你遇到的图片加载不全问题核心是两个逻辑错误叠加导致的:
UIImage(contentsOfFile:)底层采用惰性解码策略:调用该方法时只会生成图片对象的引用,不会立刻把整个图片解码加载到内存,实际解码操作会延迟到UIKit要渲染图片到屏幕时才执行- 你在给
profilePicture.image赋值后立刻调用了stopAccessingSecurityScopedResource(),直接收回了附件路径的访问权限,等到UIKit触发解码时已经没有权限读取完整的图片文件内容,只能读到部分数据,就会出现右下角灰色残缺块的情况
NotificationServiceExtension中没有该问题,是因为ServiceExtension阶段系统会提前完成附件的预处理和解码,不存在权限提前回收的冲突。
修复方案
你需要强制图片在权限有效期内完成完整解码,再收回访问权限,修改后的代码如下:
func didReceive(_ notification: UNNotification) { let content = notification.request.content self.name.text = content.title self.subject.text = content.subtitle self.body.text = content.body if let attachment = content.attachments.first, attachment.url.startAccessingSecurityScopedResource() { defer { // 用defer保证无论逻辑怎么走都会在退出作用域时回收权限 attachment.url.stopAccessingSecurityScopedResource() } if let rawImage = UIImage(contentsOfFile: attachment.url.path) { // 强制解码图片:把图片绘制到上下文,生成完全解码后的新图片对象 UIGraphicsBeginImageContextWithOptions(rawImage.size, false, UIScreen.main.scale) rawImage.draw(at: .zero) let decodedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() self.profilePicture.image = decodedImage } } }
额外优化点
- 如果是大图场景,可以提前裁剪到和
profilePicture控件匹配的尺寸再解码,减少内存占用,提升渲染速度
内容的提问来源于stack exchange,提问作者Tim Langner
相关产品推荐
相关产品推荐

