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
相关产品推荐
相关产品推荐

