2015-10-26 9 views
6

Sto cercando di inserire nel var contacts: [CNContact] = [] il var store = CNContactStore(), ma non ho trovato il codice giusto per questo lavoro, ho trovato questa funzione che ho bisogno di dare un nome checome retrive tutti CNContactStore dal dispositivo senza filtro

func findContactsWithName(name: String) { 
    AppDelegate.sharedDelegate().checkAccessStatus({ (accessGranted) -> Void in 
     if accessGranted { 
      dispatch_async(dispatch_get_main_queue(), {() -> Void in 
       do { 
        let predicate: NSPredicate = CNContact.predicateForContactsMatchingName(name) 
        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.") 
       } 
      }) 
     } 
    }) 
} 

voglio inserire self.contacts tutti i record e non solo uno con nome uguale

+0

Salve la seguente riga di codice indicherà nome, cognome, data di nascita. ** let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()] ** Se voglio recuperare tutti i dettagli di un contatto come recuperare ?. –

risposta

8

Aggiornamento

sulla base di com dall'OP, prova la seguente API CNContactFetchRequest per recuperare tutti i contatti senza filtro. Lo faccio su un thread in background per ridurre qualsiasi numero possibile di enormi numeri di contatti.

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) 

      }) 
     }) 
    } 

generale che normalmente impostare un predicato a zero per recuperare tutti i contatti quando si utilizza CNContactFetchRequest classe piuttosto che come descritto nel codice.

Nota

Se si desidera utilizzare l'API esistente poi mi consiglia di impostare il predicato true:

NSPredicate(value: true) 

Questo dovrebbe far tornare tutti i contatti. Se ciò non funziona, prendere in considerazione il passaggio all'API CNConctactFetchRequest per enumerare i Contatti. In tal caso, è possibile impostare il predicato su nil per recuperare tutti i contatti (utilizzando CNConctactFetchRequest).

CNContactFetch-Predicate

Questo è come si potrebbe modificare il metodo esistente:

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.") 
        } 
       }) 
      } 
     }) 
    } 

E da usare:

let contacts = findContacts() 

Apple ha un campione di più semplice:

let store = CNContactStore() 
let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey]) 

Per il vostro caso d'uso, si potrebbe tentare di modificare l'esempio di Apple in questo modo:

//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]) 

More Apple Samples for the Contacts Framework

+2

Sto per terminare l'app a causa dell'eccezione non rilevata 'CNInvalidPredicateException', motivo: 'Il predicato TRUEPREDICATE non è un predicat valido del contatto – shaharnakash

+0

@shaharnakash - Vedi l'esempio di CNContactFetchRequest fornito. Per favore fatemi sapere se funziona nel vostro caso? –

+0

C ora funziona, io uso come suggerisci let fetchRequest = CNContactFetchRequest (keysToFetch: keysToFetch) e ora tutto perfetto :) – shaharnakash

8

Modified risposta di Tommie C per XCode 8 & Swift 3.0.

func findContactsOnBackgroundThread (completionHandler:@escaping (_ contacts:[CNContact]?)->()) { 

    DispatchQueue.global(qos: .userInitiated).async(execute: {() -> Void in 

     let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),CNContactPhoneNumbersKey] as [Any] //CNContactIdentifierKey 
     let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch as! [CNKeyDescriptor]) 
     var contacts = [CNContact]() 
     CNContact.localizedString(forKey: CNLabelPhoneNumberiPhone) 

     if #available(iOS 10.0, *) { 
      fetchRequest.mutableObjects = false 
     } else { 
      // Fallback on earlier versions 
     } 
     fetchRequest.unifyResults = true 
     fetchRequest.sortOrder = .userDefault 

     let contactStoreID = CNContactStore().defaultContainerIdentifier() 
     print("\(contactStoreID)") 


     do { 

      try CNContactStore().enumerateContacts(with: 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) 
     } 

     DispatchQueue.main.async(execute: {() -> Void in 
      completionHandler(contacts) 

     }) 
    }) 
} 

override func viewDidLoad() { 
    findContactsOnBackgroundThread { (contacts) in 
      self.contactsList = contacts 
      self.tableView.reloadData() 
     } 
}