You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何按单电话号码维度获取通讯录联系人?

问题解答

首先明确:无法仅通过NSPredicate实现你想要的效果。

原因是CNContact对象对应通讯录中的单个联系人条目,CNContactFetchRequest返回的是完整的联系人实例,NSPredicate的作用只是筛选哪些联系人被纳入结果集(比如过滤掉没有电话号码的联系人),但不能将一个联系人的多个电话号码拆分成独立的条目返回。

如果你必须得到每个条目仅含单个电话号码的结构,只能在获取联系人后进行拆分处理。这里可以自定义一个简单的结构体来存储拆分后的结果,示例代码如下:

// 自定义结构体存储单个联系人+单个电话号码
struct ContactEntry {
    let fullName: String
    let phoneNumber: String
}

func fetchContacts() {
    let store = CNContactStore()
    let keysToFetch = [
        CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
        CNContactPhoneNumbersKey as any CNKeyDescriptor
    ]
    let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
    var result: [ContactEntry] = []
    
    do {
        try store.enumerateContacts(with: fetchRequest) { contact, stop in
            let fullName = CNContactFormatter.string(from: contact, style: .fullName) ?? ""
            // 遍历每个电话号码,生成独立条目
            for phoneNumber in contact.phoneNumbers {
                let numberString = phoneNumber.value.stringValue
                result.append(ContactEntry(fullName: fullName, phoneNumber: numberString))
            }
        }
        // 打印结果
        result.forEach { entry in
            print("Contact(fullName : \"\(entry.fullName)\", phoneNumber: \"\(entry.phoneNumber)\")")
        }
    } catch let error {
        print("Fetching contacts failed: \(error)")
    }
}

这段代码会输出你期望的格式:

Contact(fullName : "John Appleseed", phoneNumber: "888-555-5512")
Contact(fullName : "John Appleseed", phoneNumber: "888-555-1212")
Contact(fullName : "Kate Bell", phoneNumber: "(555) 564-8583")
Contact(fullName : "Kate Bell", phoneNumber: "(415) 555-3695")

另外,如果你想用NSPredicate过滤掉没有电话号码的联系人,可以给fetchRequest添加Predicate:

fetchRequest.predicate = NSPredicate(format: "phoneNumbers.@count > 0")

但这只是过滤掉无号码的联系人,依然无法拆分单个联系人的多个号码。

内容的提问来源于stack exchange,提问作者Jay Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 08:27:40