SuperAPI AI 工具集

axiom-contacts-ref

编程与开发

查看项目

更新于 10-16 10:54

技能介绍

本资料是 Contacts 框架的参考文档,介绍如何通过代码访问系统联系人数据库。Contacts 提供对联系人的程序化访问,ContactsUI 提供用于联系人选择与显示的系统视图控制器,ContactProvider 让应用能把自身来源的联系人暴露给系统。支持平台包括 iOS 9.0+、iPadOS 9.0+、macOS 10.11+、Mac Catalyst 13.1+、watchOS 2.0+、visionOS 1.0+。

一、用途与整体结构 该参考文档用于指导开发者读取、创建、修改、删除、格式化与导入导出系统联系人,并支持与系统通讯录生态的双向集成。内容分为多个部分:CNContactStore、联系人键描述符、CNMutableContact、CNSaveRequest、CNContactFormatter、CNContactVCardSerialization、ContactsUI、联系人访问按钮(iOS 18+)、contactAccessPicker(iOS 18+)、ContactProvider 框架(iOS 18+)、变更历史(TN3149)、错误参考、平台可用性。

二、CNContactStore CNContactStore 是访问联系人数据的主要入口。文档提示:获取方法会执行 I/O,应避免在主线程使用。授权方面,可通过 CNContactStore.authorizationStatus(for:) 检查状态,返回 .notDetermined、.restricted、.denied、.authorized、.limited(iOS 18+);通过 store.requestAccess(for:) 请求访问并返回 Bool。Info.plist 中必须提供 NSContactsUsageDescription,否则会崩溃;读取或写入备注字段需要特殊授权 com.apple.developer.contacts.notes,且需 Apple 批准。 获取联系人方式包括:按标识符使用 unifiedContact(withIdentifier:keysToFetch:),按谓词使用 unifiedContacts(matching:keysToFetch:),获取当前用户名片使用 unifiedMeContact(withKeysToFetch:),以及通过 CNContactFetchRequest 进行内存友好的枚举,可设置谓词与排序顺序,并使用 stop 提前中断。内置谓词支持按姓名、电子邮件地址、电话号码、标识符、群组、容器匹配。容器与群组管理支持 containers(matching:)、groups(matching:) 以及 defaultContainerIdentifier。CNContainer 类型有 .local、.exchange、.cardDAV、.unassigned。变更跟踪可通过 currentHistoryToken 保存以实现增量同步;注册 .CNContactStoreDidChange 通知可在变更时重新获取。保存操作通过 CNSaveRequest 的 add、update、delete 方法并执行 execute(request)。

三、CNContact 键描述符 文档强调必须明确指定要获取的属性,访问未获取的属性会抛出 CNContactPropertyNotFetchedException。列出了常见键常量,涵盖标识符、姓名各部分、昵称、组织、职务、部门、电话、电子邮件、邮政地址、URL、社交资料、即时消息地址、生日、非公历生日、日期、备注(需授权)、图像数据、缩略图数据、图像是否可用、联系人关系、联系人类型(个人或组织)。提供了便捷描述符,例如 CNContactFormatter.descriptorForRequiredKeys(for:) 用于姓名显示,CNContactVCardSerialization.descriptorForRequiredKeys() 用于 vCard 导出,建议优先使用格式化器描述符而非手动键列表。

四、CNMutableContact CNMutableContact 是 CNContact 的可变子类,文档说明其非线程安全,跨线程访问应使用不可变的 CNContact。可创建并设置姓名、组织、职务、电话、电子邮件、邮政地址、生日、照片等。删除值时,字符串与数组设为空,其他属性设为 nil。有一条约束:只能修改从联系人数据库获取过的属性值。

五、CNSaveRequest 用于对联系人、群组、子群组进行批量操作。平台为 iOS 9.0+、iPadOS 9.0+、macOS 10.11+、Mac Catalyst 13.1+,不支持 watchOS。支持添加、更新、删除联系人;添加、更新、删除群组;添加或移除群组成员;添加或移除子群组。属性包括 shouldRefetchContacts(执行后重新获取新增或更新的联系人)与 transactionAuthor(标识变更者,用于变更历史过滤)。执行时使用 store.execute(request),并发冲突时采用“最后更改生效”策略。

六、CNContactFormatter 提供区域感知的姓名格式化。可生成字符串或属性字符串,并查询姓名顺序(.givenNameFirst、.familyNameFirst)与分隔符。样式包括 .fullName 与 .phoneticFullName。

七、CNContactVCardSerialization 支持将联系人导出为 vCard 数据、从 vCard 数据导入联系人,并提供导出所需键描述符。

八、ContactsUI CNContactPickerViewController(iOS 9+)允许用户在不授予应用级授权的情况下选择联系人,应用收到一次性快照。可设置 displayedPropertyKeys,并在展示前设置谓词:predicateForEnablingContact(哪些联系人可选)、predicateForSelectionOfContact(自动选择整条联系人)、predicateForSelectionOfProperty(可单独选择的属性)。注意谓词更改仅在视图展示前生效。委托方法支持选择单个联系人、多个联系人、属性,以及取消。CNContactViewController(iOS 9+)用于显示单个联系人,有三种初始化方式:已有联系人、未知联系人、新建联系人;可设置 allowsEditing、allowsActions、displayedPropertyKeys,并高亮属性。

九、联系人访问按钮(iOS 18+) ContactAccessButton 是注重隐私的 SwiftUI 组件,传入查询字符串并返回标识符回调。支持标题选项(.defaultText、.email、.phone)与样式修饰符(字体、前景色、着色、标题、图像宽度)。文档说明仅在按钮可读(文字与背景对比充分)、无遮挡(完整可见未被裁剪)、以及有效点击(真实用户交互而非模拟)时才授予访问。

十、contactAccessPicker(iOS 18+) 用于管理受限访问联系人集合的模态表单,适合批量或非即时场景。通过 isPresented 控制展示,回调返回新允许的联系人标识符。与 CNContactPickerViewController 的区别:contactAccessPicker 改变持久访问权限,后者提供一次性快照。

十一、ContactProvider 框架(iOS 18+) 让应用从第三方来源向系统通讯录生态暴露联系人。架构上,主应用通过 ContactProviderManager 控制扩展,扩展向系统枚举联系人,双方通过 App Group 共享容器通信。ContactProviderManager 仅限主应用使用,提供 enable、disable、reset、invalidate、signalEnumerator 以及 isEnabled 属性。ContactProviderExtension 协议包含 configure、enumerator、invalidate 方法,Info.plist 中需声明扩展点 com.apple.contact.provider.extension。枚举有两种模式:内容枚举(通过 ContactItemContentObserver 全量初始同步)与变更枚举(通过 ContactItemChangeObserver 和 ContactItemSyncAnchor 增量更新)。文档列出了 ContactProvider 错误及含义,如 featureNotAvailable、deniedByUser、extensionNotFound、enumerationTimeout、cannotEnumerate、pageExpired、changeAnchorExpired、itemsLimitReached。

十二、变更历史(TN3149) CNChangeHistoryFetchRequest 支持设置起始令牌(nil 表示全量)、是否包含群组变更、是否可变对象、是否统一结果、附加联系人键描述符、排除的事务作者。CNChangeHistoryEventVisitor 协议要求实现全量重同步、新增、更新、删除事件,并可选择实现群组相关事件。必须使用访问者模式,不要用 isKindOfClass: 判断事件类型。注意 enumeratorForChangeHistoryFetchRequest:error: 仅限 Objective-C,Swift 不可用。令牌过期时返回所有联系人的 DropEverything 加 Add 事件,同一代码可处理全量与增量同步。事务作者使用反向域名表示法,用于过滤但不提供归因。

十三、错误参考与平台可用性 CNError 代码按类别列出:授权类(authorizationDenied、featureDisabledByUser)、数据类(recordDoesNotExist、recordNotWritable、insertedRecordAlreadyExists)、验证类(validationTypeMismatch、validationMultipleErrors)、历史类(changeHistoryExpired、changeHistoryInvalidAnchor、changeHistoryInvalidFetchRequest)。错误的 userInfo 提供 affectedRecords、affectedRecordIdentifiers、keyPaths。文档最后列出了平台可用性对照表。