LPLinkMetadata编解码后imageProvider属性丢失问题咨询
问题场景
在获取目标网站元数据的开发场景中,部分情况下拿到的LPLinkMetadata实例的imageProvider属性为nil,此时可通过页面其他信息生成对应的UIImage。需求为将imageProvider替换为自定义实例后,对最终生成的LPLinkMetadata对象做缓存,但测试发现即便在最简场景下,自定义赋值的imageProvider也无法被正常编码。
复现代码
let metadata = LPLinkMetadata() metadata.imageProvider = NSItemProvider(object: UIImage()) metadata.title = "Test" print(metadata.imageProvider) // 输出有效NSItemProvider实例 print(metadata.title) // 输出 "Test" // 编码后再解码 let encodedMetadata = try! NSKeyedArchiver.archivedData(withRootObject: metadata, requiringSecureCoding: false) let decodedMetadata = try! NSKeyedUnarchiver.unarchivedObject(ofClass: LPLinkMetadata.self, from: encodedMetadata) print(decodedMetadata?.imageProvider) // 输出 nil print(decodedMetadata?.title) // 输出 "Test"
问题表现
- 编码前:
metadata的imageProvider为有效NSItemProvider实例,title属性值正常为"Test" - 完成编码+解码流程后:解码得到的实例
title属性可正常读取,imageProvider属性为nil
原因说明
LPLinkMetadata自带的NSCoding归档逻辑对imageProvider字段有内置校验规则:只有系统在拉取链接元数据流程中自动生成的、带内部标识的NSItemProvider实例,才会被写入归档数据;开发者手动初始化、挂载自定义UIImage的普通NSItemProvider,不会被系统归档逻辑识别写入,因此解码后该字段为空。
可行解决方案
推荐使用自定义封装存储的方案,无审核风险,兼容性稳定:
- 不要直接归档整个
LPLinkMetadata对象 - 提取
LPLinkMetadata中所有可正常编码的业务需要字段(如title、originalURL、url、iconProvider等)单独存储 - 将自定义的
UIImage转为PNG或JPEG格式的二进制数据单独归档存储 - 读取缓存时,重新初始化一个新的
LPLinkMetadata实例,将之前存储的各字段赋值回去,同时用存好的图片数据重新生成NSItemProvider赋值给imageProvider即可。
不建议通过runtime交换方法、调用私有API的方式强制让系统归档自定义
imageProvider,这类实现会存在App Store审核被拒的风险,同时不同系统版本下兼容性无法保证。
内容的提问来源于stack exchange,提问作者Will
相关产品推荐
相关产品推荐

