Contacts(Apple Documentation)
Contacts/CNContactStore(Apple Documentation)
1. 获取权限
- 需要在
Info.plist中添加NSContactsUsageDescription键,并提供一个描述,说明为什么需要访问联系人。 - 由于涉及到用户隐私,确保在请求权限时提供清晰的解释。
Q: 获取联系人有几种方法,有什么区别
A:
在 iOS 中,获取系统联系人的方法主要依赖于 Contacts 框架(CNContactStore)。根据不同的需求和场景,获取联系人的方法可以分为以下几种,每种方法有其特点和适用场景:
1. 使用 CNContactFetchRequest 枚举联系人
- 特点:
- 适用于批量获取联系人。
- 可以指定需要获取的联系人字段(如名字、电话、邮箱等)。
- 通过回调逐条返回联系人,适合处理大量联系人。
- 代码示例:
let store = CNContactStore() let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor] let request = CNContactFetchRequest(keysToFetch: keysToFetch) do { try store.enumerateContacts(with: request) { contact, stop in print("Name: \(contact.givenName) \(contact.familyName)") for phoneNumber in contact.phoneNumbers { print("Phone: \(phoneNumber.value.stringValue)") } } } catch { print("Failed to fetch contacts: \(error)") } - 适用场景:
- 需要获取所有联系人。
- 需要逐条处理联系人数据。
2. 使用 CNContactStore 的 unifiedContacts(matching:keysToFetch:) 方法
- 特点:
- 根据条件(如名字、电话等)查询联系人。
- 返回一个包含匹配联系人的数组。
- 需要指定查询条件(
NSPredicate)和需要获取的字段。
- 代码示例:
let store = CNContactStore() let predicate = CNContact.predicateForContacts(matchingName: "John") let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor] do { let contacts = try store.unifiedContacts(matching: predicate, keysToFetch: keysToFetch) for contact in contacts { print("Name: \(contact.givenName) \(contact.familyName)") for phoneNumber in contact.phoneNumbers { print("Phone: \(phoneNumber.value.stringValue)") } } } catch { print("Failed to fetch contacts: \(error)") } - 适用场景:
- 根据特定条件(如名字、电话等)查询联系人。
- 需要快速获取符合条件的联系人。
3. 使用 CNContactStore 的 unifiedContact(withIdentifier:keysToFetch:) 方法
- 特点:
- 根据联系人的唯一标识符(
identifier)获取单个联系人。 - 需要提前知道联系人的
identifier。
- 根据联系人的唯一标识符(
- 代码示例:
let store = CNContactStore() let contactIdentifier = "12345" // 联系人的唯一标识符 let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor] do { let contact = try store.unifiedContact(withIdentifier: contactIdentifier, keysToFetch: keysToFetch) print("Name: \(contact.givenName) \(contact.familyName)") for phoneNumber in contact.phoneNumbers { print("Phone: \(phoneNumber.value.stringValue)") } } catch { print("Failed to fetch contact: \(error)") } - 适用场景:
- 已知联系人唯一标识符,需要获取特定联系人的详细信息。
4. 使用 CNContactStore 的 containers(matching:) 方法
- 特点:
- 获取联系人容器(
CNContainer),每个容器包含一组联系人。 - 适用于需要区分不同来源的联系人(如 iCloud、本地、Exchange 等)。
- 获取联系人容器(
- 代码示例:
let store = CNContactStore() do { let containers = try store.containers(matching: nil) for container in containers { print("Container: \(container.name)") } } catch { print("Failed to fetch containers: \(error)") } - 适用场景:
- 需要区分不同来源的联系人。
- 需要获取特定容器中的联系人。
5. 使用 CNContactStore 的 groups(matching:) 方法
- 特点:
- 获取联系人分组(
CNGroup),每个分组包含一组联系人。 - 适用于需要按分组获取联系人。
- 获取联系人分组(
- 代码示例:
let store = CNContactStore() do { let groups = try store.groups(matching: nil) for group in groups { print("Group: \(group.name)") } } catch { print("Failed to fetch groups: \(error)") } - 适用场景:
- 需要按分组获取联系人。
- 需要管理联系人分组。
6. 使用 CNContactStore 的 defaultContainerIdentifier() 方法
- 特点:
- 获取默认联系人容器的标识符。
- 适用于需要操作默认容器中的联系人。
- 代码示例:
let store = CNContactStore() let defaultContainerIdentifier = store.defaultContainerIdentifier() print("Default Container Identifier: \(defaultContainerIdentifier)") - 适用场景:
- 需要操作默认容器中的联系人。
方法对比
| 方法 | 特点 | 适用场景 |
|---|---|---|
enumerateContacts(with:) | 批量获取联系人,逐条回调 | 获取所有联系人,逐条处理 |
unifiedContacts(matching:keysToFetch:) | 根据条件查询联系人,返回匹配的数组 | 根据条件查询联系人 |
unifiedContact(withIdentifier:keysToFetch:) | 根据唯一标识符获取单个联系人 | 获取特定联系人的详细信息 |
containers(matching:) | 获取联系人容器,区分不同来源的联系人 | 区分不同来源的联系人 |
groups(matching:) | 获取联系人分组,按分组获取联系人 | 按分组获取联系人 |
defaultContainerIdentifier() | 获取默认联系人容器的标识符 | 操作默认容器中的联系人 |
总结
- 如果需要获取所有联系人,推荐使用
enumerateContacts(with:)。 - 如果需要根据条件查询联系人,推荐使用
unifiedContacts(matching:keysToFetch:)。 - 如果需要获取特定联系人,推荐使用
unifiedContact(withIdentifier:keysToFetch:)。 - 如果需要区分不同来源或分组的联系人,可以使用
containers(matching:)或groups(matching:)。
根据具体需求选择合适的方法,可以提高代码的效率和可读性。