iOS13下CNMutableContact的note与imageData属性设置失效如何解决
CNMutableContact的note、imageData属性设置不生效问题解决方案
1. note属性不生效原因
- iOS 13及以上系统对联系人备注字段做了权限隔离,仅申请普通的联系人读写权限无法修改note字段,需要额外在苹果开发者账号后台申请
com.apple.developer.contacts.notes专属entitlement权限,添加到项目的配置文件中才能正常读写该字段。 - 如果你是将联系人导出共享(比如通过vCard、系统分享面板),默认导出规则不会包含note字段,需要显式指定导出的键集合包含
CNContactNoteKey才会生效,示例如下:
// 导出vCard时正确写法 let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactNoteKey, CNContactImageDataKey] as [CNKeyDescriptor] do { let vcardData = try CNContactVCardSerialization.data(from: [contact], includingKeys: keys) // 后续使用vcardData做分享/保存 } catch { print("导出vCard失败: \(error)") }
2. imageData属性不生效原因
- 你的现有代码使用
try? Data(contentsOf: url)读取数据,该写法会忽略所有错误:如果url无效、网络请求失败、本地文件不存在都会直接返回nil,导致imageData没有被赋值。建议先判断数据是否正常读取,修改写法如下:
if let imageUrl = self.getImgLogo(), let url = URL(string: imageUrl) { do { let imgData = try Data(contentsOf: url) // 可选:压缩图片避免数据过大被系统忽略 if let img = UIImage(data: imgData), let compressedData = img.jpegData(compressionQuality: 0.7) { contact.imageData = compressedData } } catch { print("读取头像数据失败: \(error)") } }
- 远程url的
Data(contentsOf:)是同步阻塞请求,不能在主线程调用,否则会被系统判定为卡顿直接中断,导致数据读取失败,建议异步下载图片后再赋值给contact。 - 联系人头像数据存在大小限制,超过阈值的图片会被系统自动丢弃,建议压缩到1MB以内再赋值。
- 共享/导出时同样需要在键集合中加入
CNContactImageDataKey才会包含头像数据。
3. 保存到系统通讯录的额外注意点
如果你的场景是将联系人写入系统通讯录,发起保存请求时也要确保请求包含对应的权限:
let store = CNContactStore() let saveRequest = CNSaveRequest() saveRequest.add(contact, toContainerWithIdentifier: nil) do { try store.execute(saveRequest) } catch { print("保存联系人失败: \(error)") }
内容的提问来源于stack exchange,提问作者llKoull
相关产品推荐
相关产品推荐

