You need to enable JavaScript to run this app. NotificationContentExtension加载UNNotificationAttachment时UIImage显示不全如何处理
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 03:36:06