能否获取包含所有键值的CNContact对象以实现联系人跨应用共享
解决CNContact全量获取与序列化共享方案
1. 全量拉取联系人字段的正确方式
CNContactFetchRequest没有无参初始化方法,所以你省略keys参数会直接报错。要获取完整联系人的所有字段,不需要手动枚举所有键值,直接使用系统提供的CNContactVCardSerialization.descriptorForRequiredKeys()即可,这个描述符已经包含了生成标准vCard格式联系人需要的全部字段,覆盖姓名、电话、地址、邮箱、组织、头像等所有内置联系人字段。
修改后的拉取代码如下:
// 直接使用系统提供的全量字段描述符,不需要手动列所有key let request = CNContactFetchRequest(keysToFetch: [CNContactVCardSerialization.descriptorForRequiredKeys()]) do { try store.enumerateContacts(with: request, usingBlock: { (contact, stopPointer) in // 这里拿到的contact已经包含所有联系人字段,不需要自己拼接基础字段 self.contacts.append(contact) }) } catch let error { print("拉取联系人失败", error) }
2. 序列化CNContact实现跨应用共享
不需要手动重建联系人的所有字段,系统自带CNContactVCardSerialization工具类,可以直接将CNContact对象序列化为通用的vCard格式数据,vCard是全平台通用的联系人标准格式,所有主流系统和应用都支持解析。
序列化发送端代码
do { // 支持单个/多个联系人批量转vCard Data let vCardData = try CNContactVCardSerialization.data(with: [selectedContact]) // 可直接将vCardData通过网络、AirDrop、系统共享面板传给其他应用 } catch { print("序列化联系人失败: \(error)") }
接收端解析代码
如果其他应用收到vCard数据,也可以直接转为完整的CNContact对象,不需要手动解析字段:
do { let contacts = try CNContactVCardSerialization.contacts(from: receivedVCardData) if let receivedContact = contacts.first { // 直接得到完整的CNContact对象使用即可 } } catch { print("解析vCard失败: \(error)") }
3. 注意事项
- 拉取联系人前确保已经在info.plist中配置了
NSContactsUsageDescription权限说明,并且获取到了用户的联系人访问授权 - 如果要通过系统共享面板分享联系人,可以将vCardData写入临时文件,后缀设置为
.vcf,再通过UIActivityViewController分享,系统会自动识别为联系人文件
内容的提问来源于stack exchange,提问作者alionthego
相关产品推荐
相关产品推荐

