Contacts 联系人

486 阅读4分钟

Contacts(Apple Documentation)

Contacts/CNContactStore(Apple Documentation)

截屏2025-02-11 13.52.37.png


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. 使用 CNContactStoreunifiedContacts(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. 使用 CNContactStoreunifiedContact(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. 使用 CNContactStorecontainers(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. 使用 CNContactStoregroups(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. 使用 CNContactStoredefaultContainerIdentifier() 方法

  • 特点
    • 获取默认联系人容器的标识符。
    • 适用于需要操作默认容器中的联系人。
  • 代码示例
    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:)

根据具体需求选择合适的方法,可以提高代码的效率和可读性。