iOS联系人如何通过电话号码获取联系人
我只想通过电话号码联系姓名和姓氏 . 我试过这个,但这太慢了,cpu超过%120 .
let contactStore = CNContactStore()
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
var contacts = [CNContact]()
do {
try contactStore.enumerateContactsWithFetchRequest(CNContactFetchRequest.init(keysToFetch: keys), usingBlock: { (contact, cursor) in
if (!contact.phoneNumbers.isEmpty) {
for phoneNumber in contact.phoneNumbers {
if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber {
do {
let libPhone = try util.parseWithPhoneCarrierRegion(phoneNumberStruct.stringValue)
let phoneToCompare = try util.getNationalSignificantNumber(libPhone)
if formattedPhone == phoneToCompare {
contacts.append(contact)
}
}catch {
print(error)
}
}
}
}
})
if contacts.count > 0 {
contactName = (contacts.first?.givenName)! + " " + (contacts.first?.familyName)!
print(contactName)
completionHandler(contactName)
}
}catch {
print(error)
}
另外,当我使用phonenumber Kit查找联系人时,它会增加cpu并给出延迟响应 .
var result: [CNContact] = []
let nationalNumber = PhoneNumberKit().parseMultiple([phoneNumber])
let number = nationalNumber.first?.toNational()
print(number)
for contact in self.addressContacts {
if (!contact.phoneNumbers.isEmpty) {
let phoneNumberToCompareAgainst = number!.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
for phoneNumber in contact.phoneNumbers {
if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber {
let phoneNumberString = phoneNumberStruct.stringValue
let nationalContactNumber = PhoneNumberKit().parseMultiple([phoneNumberString])
let nationalContactNumberString = nationalContactNumber.first?.toNational()
if nationalContactNumberString == number {
result.append(contact)
}
}
}
}
}
return result
回答(2)
SWIFT 4 UPDATE
1)添加到.plist
<key>NSContactsUsageDescription</key>
<string>Our application needs to your contacts</string>
2)如果您没有请求授权
func requestAccess() {
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
guard granted else {
DispatchQueue.main.async {
self.presentSettingsActionSheet()
}
return
}
}
}
func presentSettingsActionSheet() {
let alert = UIAlertController(title: "Permission to Contacts", message: "This app needs access to contacts in order to ...", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Go to Settings", style: .default) { _ in
let url = URL(string: UIApplicationOpenSettingsURLString)!
UIApplication.shared.open(url)
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alert, animated: true)
}
2)如果您之前要求,请检查授权状态
if CNContactStore.authorizationStatus(for: .contacts) == .authorized {
getContacts()
}
3)致电获取联系人
var contacts = [CNContact]()
func getContacts(){
let contactStore = CNContactStore()
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactImageDataAvailableKey, CNContactThumbnailImageDataKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
request.sortOrder = CNContactSortOrder.givenName
do {
try contactStore.enumerateContacts(with: request) {
(contact, stop) in
self.contacts.append(contact)
}
}
catch {
print("unable to fetch contacts")
}
}
4) THIS IS THE FUNCTION TO GET THE CONTACT NAME OR BY NUMBER
func getNameFromContacts(number: String) -> String {
var contactFetched : CNContact
var contactName = ""
if contacts.count > 0 {
let numberToBeCompared = number.components(separatedBy:CharacterSet.decimalDigits.inverted).joined(separator: "")
for c in contacts {
for n in c.phoneNumbers {
if let numberRetrived = n.value as? CNPhoneNumber {
let numberRetrivedFixed = numberRetrived.stringValue.components(separatedBy:CharacterSet.decimalDigits.inverted).joined(separator: "")
if numberRetrivedFixed.elementsEqual(numberToBeCompared){
contactName = c.givenName
// OR get the contact --> c
contactFetched = c
}
}
}
}
return contactName
} else {
return ""
}
}
2 years ago
您的实施问题是您在每次搜索时访问地址簿 .
相反,如果您在第一次访问后保留内存中的地址簿内容,则不会达到此高CPU使用率 .
.
I tested it with a very big address book, it works smoothly.
这是整个视图控制器拼凑在一起以供参考 .
我使用flohei's answer作为懒惰的var部分 .