2015-10-26 10 views
6

ich in var contacts: [CNContact] = [] die var store = CNContactStore() einzufügen bin versucht, aber ich habe nicht den richtigen Code für diesen Job finden, fand ich diese Funktion, die ich, die einen Namen geben müssenwie alle CNContactStore von Gerät retrive ohne Filter

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

ich möchte self.contacts alle Datensätze einfügen und nicht nur einer mit dem Namen gleich

+0

Hallo die folgende Zeile des Codes wird gibt Vorname, Familienname, Geburtstag. ** let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()] ** Wenn ich alle Details eines Kontakts abholen möchte? –

Antwort

8

aktualisieren

Basierend auf com Bitte versuchen Sie die folgende CNContactFetchRequest-basierte API, um alle Kontakte ohne einen Filter abzurufen. Ich führe dies auf einem Hintergrund-Thread, um mögliche Probleme große Anzahl von Kontakten zu reduzieren.

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) 

      }) 
     }) 
    } 

Im Allgemeinen Sie normalerweise ein Prädikat gesetzt würde auf Null alle Kontakte abzurufen, wenn CNContactFetchRequest Klasse anstatt wie im Code beschrieben ist.

Hinweis

Wenn Sie Ihre bestehende API verwenden dann empfehle ich das Prädikat true setzen:

NSPredicate(value: true) 

Dies sollte alle Kontakte zurückkehren machen. Wenn dies nicht funktioniert, ziehen Sie den Wechsel zur CNConctactFetchRequest-API zur Auflistung der Kontakte in Betracht. In diesem Fall könnten Sie das Prädikat auf Null setzen, um alle Kontakte abzurufen (mit CNConctactFetchRequest).

CNContactFetch-Predicate

Dies ist, wie Sie vielleicht das bestehende Verfahren ändern:

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

Und zu verwenden:

let contacts = findContacts() 

hat Apple ein einfacheres Beispiel:

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

Für Ihren Anwendungsfall, können Sie versuchen, das Apple-Probe wie folgt zu ändern:

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

Ich bin terminiert App aufgrund der nicht abgefangenen Ausnahme 'CNInvalidPredicateException', Grund: 'Das Prädikat TRUEPREDICATE ist kein gültiges Kontaktprädikat – shaharnakash

+0

@shaharnakash - Siehe das CNContactFetchRequest-Beispiel zur Verfügung gestellt. Bitte lassen Sie mich wissen, ob das in Ihrem Fall funktioniert? –

+0

C jetzt seine Arbeit, ich benutze, wie Sie vorschlagen, lassen Sie fetchRequest = CNContactFetchRequest (keysToFetch: keysToFetch) und jetzt alles perfekt :) – shaharnakash

8

Modified Tommie C 's für XCode 8 & Swift 3.0 Antwort.

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() 
     } 
}