Swift verschachtelte Filteroptimierung?

Ich habe versucht, in Swift etwas zu tun, das in Objective-C mit KVC einfach ist. Das neueContacts frameworkas in iOS9 hinzugefügte @ ist zum größten Teil einfacher zu verwenden als dasold AddressBook API. Es scheint jedoch schwierig zu sein, einen Kontakt über seine Mobiltelefonnummer zu finden. Die Prädikate zum Auffinden von Kontakten sind auf den Namen und die eindeutige Kennung beschränkt. In Objective-C können Sie alle Kontakte abrufen und dann mit einem NSPredicate eine KVC-Abfrage filtern. Die Struktur ist:

CNContact-> phoneNumbers -> (String, CNPhoneNumber-> stringValue)

Setzen Sie im folgenden Code fort, über den ich die Kontakte abgerufen habe:

let keys = [CNContactEmailAddressesKey,CNContactPhoneNumbersKey, CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName)]
let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
var contacts:[CNContact] = []
try! CNContactStore().enumerateContactsWithFetchRequest(fetchRequest) { ...

Ich möchte den stringValue mit einem bekannten Wert vergleichen. Folgendes habe ich bisher von einem Spielplatz:

import UIKit
import Contacts

let JennysPhone    = "111-867-5309"
let SomeOtherPhone = "111-111-2222"
let AndAThirdPhone = "111-222-5309"

let contact1 = CNMutableContact()
contact1.givenName = "Jenny"
let phone1 = CNPhoneNumber(stringValue: JennysPhone)
let phoneLabeled1 = CNLabeledValue(label: CNLabelPhoneNumberMobile, value: phone1)
contact1.phoneNumbers.append(phoneLabeled1)

let contact2 = CNMutableContact()
contact2.givenName = "Billy"
let phone2 = CNPhoneNumber(stringValue: SomeOtherPhone)
let phoneLabeled2 = CNLabeledValue(label: CNLabelPhoneNumberMobile, value: phone2)
contact2.phoneNumbers.append(phoneLabeled2)

let contact3 = CNMutableContact()
contact3.givenName = "Jimmy"
let phone3 = CNPhoneNumber(stringValue: SomeOtherPhone)
let phoneLabeled3 = CNLabeledValue(label: CNLabelPhoneNumberMobile, value: phone3)
contact3.phoneNumbers.append(phoneLabeled3)

let contacts = [contact1, contact2, contact3]

let matches = contacts.filter { (contact) -> Bool in
    let phoneMatches = contact.phoneNumbers.filter({ (labeledValue) -> Bool in
        if let v = labeledValue.value as? CNPhoneNumber
        {
            return v.stringValue == JennysPhone
        }
        return false
    })
    return phoneMatches.count > 0
}

if let jennysNum = matches.first?.givenName
{
    print("I think I found Jenny:  \(jennysNum)")
}
else
{
    print("I could not find Jenny")
}

Dies funktioniert, ist aber nicht effizient. Auf einem Gerät müsste ich dies in einem Hintergrund-Thread ausführen, und es könnte eine Weile dauern, wenn die Person viele Kontakte hat. Gibt es eine bessere Möglichkeit, einen Kontakt über die Telefonnummer (oder E-Mail-Adresse, dieselbe Idee) mithilfe des neuen iOS-Frameworks für Kontakte zu finden?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage