Обновить
Основываясь на комментарии от OP, попробуйте следующий API на основе CNContactFetchRequest, чтобы получить все контакты без фильтра. Я запускаю это в фоновом потоке, чтобы уменьшить количество возможных проблем с огромным количеством контактов.
func findContactsOnBackgroundThread ( completionHandler:(contacts:[CNContact]?)->()) {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),CNContactPhoneNumbersKey] //CNContactIdentifierKey
let fetchRequest = CNContactFetchRequest( keysToFetch: keysToFetch)
var contacts = [CNContact]()
CNContact.localizedStringForKey(CNLabelPhoneNumberiPhone)
fetchRequest.mutableObjects = false
fetchRequest.unifyResults = true
fetchRequest.sortOrder = .UserDefault
let contactStoreID = CNContactStore().defaultContainerIdentifier()
print("\(contactStoreID)")
do {
try CNContactStore().enumerateContactsWithFetchRequest(fetchRequest) { (contact, stop) -> Void in
//do something with contact
if contact.phoneNumbers.count > 0 {
contacts.append(contact)
}
}
} catch let e as NSError {
print(e.localizedDescription)
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
completionHandler(contacts: contacts)
})
})
}
Вообще говоря, при использовании CNContactFetchRequest, а не так, как описано в вашем коде.
Примечание
Если вы хотите использовать существующий API, я рекомендую установить для предиката значение true:
NSPredicate(value: true)
Это должно вернуть все контакты. Если это не сработает, рассмотрите возможность переключения на API CNConctactFetchRequest для перечисления контактов. В этом случае вы можете установить для предиката значение nil, чтобы получить все контакты (используя CNConctactFetchRequest).
Вот как вы можете изменить существующий метод:
func findContacts()->[CNContact] {
AppDelegate.sharedDelegate().checkAccessStatus({ (accessGranted) -> Void in
if accessGranted {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
do {
let predicate: NSPredicate = NSPredicate(value: true)
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()]
self.contacts = try self.store.unifiedContactsMatchingPredicate(predicate, keysToFetch:keysToFetch)
self.tableView.reloadData()
}
catch {
print("Unable to refetch the selected contact.")
}
})
}
})
}
И использовать:
let contacts = findContacts()
У Apple есть более простой пример:
let store = CNContactStore()
let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey])
В вашем случае вы можете попробовать изменить образец Apple следующим образом:
//Use the reference to look up additional keys constants that you may want to fetch
let store = CNContactStore()
let contacts = try store.unifiedContactsMatchingPredicate(NSPredicate(value: true), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey])
Подробнее Образцы Apple для платформы контактов
person
Tommie C.
schedule
26.10.2015