Das Problem mit Ihrer Implementierung ist, dass Sie auf das Adressbuch in jeder Suche zugreifen, die Sie machen.
Wenn Sie stattdessen den Adressbuchinhalt nach dem ersten Zugriff im Speicher halten, erreichen Sie diese hohe CPU-Auslastung nicht.
Zuerst einen faulen var in Ihrem Controller hält, die den Adreßbuch Inhalt halten:
lazy var contacts: [CNContact] = {
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]
// Get all the containers
var allContainers: [CNContainer] = []
do {
allContainers = try contactStore.containersMatchingPredicate(nil)
} catch {
print("Error fetching containers")
}
var results: [CNContact] = []
// Iterate all containers and append their contacts to our results array
for container in allContainers {
let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier)
do {
let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
results.appendContentsOf(containerResults)
} catch {
print("Error fetching results for container")
}
}
return results
}()
- Iterate durch den In-Memory-Array, wenn Sie schauen für einen Kontakt mit einer bestimmten Telefonnummer:
.
func searchForContactUsingPhoneNumber(phoneNumber: String) -> [CNContact] {
var result: [CNContact] = []
for contact in self.contacts {
if (!contact.phoneNumbers.isEmpty) {
let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
for phoneNumber in contact.phoneNumbers {
if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber {
let phoneNumberString = phoneNumberStruct.stringValue
let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
if phoneNumberToCompare == phoneNumberToCompareAgainst {
result.append(contact)
}
}
}
}
}
return result
}
ich es mit einem sehr großen Adressbuch getestet, es funktioniert reibungslos.
Hier ist der gesamte View-Controller als Referenz zusammengeflickt.
import UIKit
import Contacts
class ViewController: UIViewController {
lazy var contacts: [CNContact] = {
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]
// Get all the containers
var allContainers: [CNContainer] = []
do {
allContainers = try contactStore.containersMatchingPredicate(nil)
} catch {
print("Error fetching containers")
}
var results: [CNContact] = []
// Iterate all containers and append their contacts to our results array
for container in allContainers {
let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier)
do {
let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
results.appendContentsOf(containerResults)
} catch {
print("Error fetching results for container")
}
}
return results
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let contact = searchForContactUsingPhoneNumber("(555)564-8583")
print(contact)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func searchForContactUsingPhoneNumber(phoneNumber: String) -> [CNContact] {
var result: [CNContact] = []
for contact in self.contacts {
if (!contact.phoneNumbers.isEmpty) {
let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
for phoneNumber in contact.phoneNumbers {
if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber {
let phoneNumberString = phoneNumberStruct.stringValue
let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
if phoneNumberToCompare == phoneNumberToCompareAgainst {
result.append(contact)
}
}
}
}
}
return result
}
}
Ich verwendete flohei's answer für die Lazy Var Teil.
Irgendwelche Vorschläge oder Hilfe? –
Glauben Sie nicht, dass es möglich ist – user3237732
Ich versuche nur, Name und Nachname von der Telefonnummer zu bekommen und kann es nicht bekommen? Es ist interessant, wie kann whatsapp das tun? –