Otimização rápida de filtro aninhado?
Eu estava tentando fazer algo no Swift que seria fácil no Objective-C usando o KVC. O novoEstrutura de contatos adicionado no iOS9 é geralmente mais fácil de usar do que oAPI antiga do AddressBook. Mas encontrar um contato pelo número do celular parece difícil. Os predicados fornecidos para localizar contatos estão limitados ao nome e ao identificador exclusivo. No Objective-C, você pode obter todos os contatos e, em seguida, usar um NSPredicate para filtrar uma consulta KVC. A estrutura é:
CNContact-> phoneNumbers -> (String, CNPhoneNumber-> stringValue)
Suponha no código abaixo que busquei os contatos via:
let keys = [CNContactEmailAddressesKey,CNContactPhoneNumbersKey, CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName)]
let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
var contacts:[CNContact] = []
try! CNContactStore().enumerateContactsWithFetchRequest(fetchRequest) { ...
Eu quero comparar o stringValue com um valor conhecido. Aqui está o que eu tenho até agora em um playground:
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")
}
Isso funciona, mas não é eficiente. Em um dispositivo, eu precisaria executar isso em um encadeamento em segundo plano, e poderia demorar um pouco se a pessoa tivesse muitos contatos. Existe uma maneira melhor de encontrar um contato por número de telefone (ou endereço de e-mail, mesma ideia) usando a nova estrutura de contatos do iOS?