2015-11-28 23 views
11

我知道ios的swift有一个Contacts Framework我可以获取联系人,但我找不到任何方法来获取所有联系人,我可以访问该数组中的每个联系人。所有提取联系人的方法似乎都需要某种条件。有什么方法可以将所有的联系人联系在一起?获取ios Swift中的所有联系人?

感谢

+1

看到这样一个问题:http://stackoverflow.com/questions/3747844/get-a-list-of-all-contacts-on-ios – Ollie

+0

@Ollie OP正在为“联系人框架”寻找解决方案,而您发布的链接仍然是ABAddressBook,我认为这没有帮助。 – Christopher

+0

@Christopher该问题的许多解决方案实际上都使用联系人框架。第二个答案给出了详细的解释。 – Ollie

回答

10

许多疑难联系框架问题,建议循环访问各种容器(帐户)。但是,Apple的文档将“统一联系人”描述为

代表同一个人的不同帐户中的联系人可能会自动链接在一起。链接的联系人在OS X和iOS应用程序中显示为统一联系人。统一联系人是合并到一个联系人中的一组链接联系人的内存中暂时视图。

默认情况下,联系人框架返回统一联系人。每个获取的统一联系人(CNContact)对象都有自己的唯一标识符,该标识符与链接联系人组中的任何单个联系人标识符不同。重新提取统一联系人应使用其标识符。获取的在单个阵列中(部分,基于键)联系人的列表 Source

那么最简单的方法,将是以​​下几点:

var contacts = [CNContact]() 
    let keys = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName)] 
    let request = CNContactFetchRequest(keysToFetch: keys) 

    do { 
     try self.contactStore.enumerateContactsWithFetchRequest(request) {    
      (contact, stop) in 
      // Array containing all unified contacts from everywhere 
      contacts.append(contact) 
     } 
    } 
    catch { 
     print("unable to fetch contacts") 
    } 
+0

非常有帮助。如果我想获取姓名和号码,并且用户有多个号码如何解决该情况 – Bora

+0

CNContact返回CNPhoneNumbers数组。您可以简单地获取数组中的第一个数字,或遍历列表并解析电话号码的CNLabeledValues以找到您想要的数字,例如“工作”或“移动” –

+0

似乎不适用于iOS 11/Swift 4 ... – leanne

4
// You may add more "keys" to fetch referred to official documentation 
    let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName)] 

    // The container means 
    // that the source the contacts from, such as Exchange and iCloud 
    var allContainers: [CNContainer] = [] 
    do { 
     allContainers = try store.containersMatchingPredicate(nil) 
    } catch { 
     print("Error fetching containers") 
    } 

    var contacts: [CNContact] = [] 

    // Loop the containers 
    for container in allContainers { 
     let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier) 

     do { 
      let containerResults = try store.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch) 
      // Put them into "contacts" 
      contacts.appendContentsOf(containerResults) 
     } catch { 
      print("Error fetching results for container") 
     } 
    } 
1

斯威夫特4.我已创建类PhoneContacts。

import Foundation 
import ContactsUI 

class PhoneContacts { 

    class func getContacts(filter: ContactsFilter = .none) -> [CNContact] { 

     let contactStore = CNContactStore() 
     let keysToFetch = [ 
      CNContactFormatter.descriptorForRequiredKeys(for: .fullName), 
      CNContactPhoneNumbersKey, 
      CNContactEmailAddressesKey, 
      CNContactThumbnailImageDataKey] as [Any] 

     var allContainers: [CNContainer] = [] 
     do { 
      allContainers = try contactStore.containers(matching: nil) 
     } catch { 
      Debug.Log(message: "Error fetching containers") 
     } 

     var results: [CNContact] = [] 

     for container in allContainers { 
      let fetchPredicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier) 

      do { 
       let containerResults = try contactStore.unifiedContacts(matching: fetchPredicate, keysToFetch: keysToFetch as! [CNKeyDescriptor]) 
       results.append(contentsOf: containerResults) 
      } catch { 
       Debug.Log(message: "Error fetching containers") 
      } 
     } 
     return results 
    } 
} 

另一类

func phoneNumberWithContryCode() -> [String] { 

    let contacts = PhoneContacts.getContacts() // here calling the getContacts methods 
    var arrPhoneNumbers = [String]() 
    for contact in contacts { 
     for ContctNumVar: CNLabeledValue in contact.phoneNumbers { 
      if let fulMobNumVar = ContctNumVar.value as? CNPhoneNumber { 
       //let countryCode = fulMobNumVar.value(forKey: "countryCode") get country code 
        let MccNamVar = fulMobNumVar.value(forKey: "digits") as? String { 
         arrPhoneNumbers.append(MccNamVar) 
       } 
      } 
     } 
    } 
    return arrPhoneNumbers // here array has all contact numbers. 
} 

上述方法的调用现在,获取联系人的电子邮件和电话

enum ContactsFilter { 
    case none 
    case mail 
    case message 
} 

var phoneContacts = [PhoneContact]() // array of PhoneContact 
var filter: ContactsFilter = .none 

self.loadContacts(filter: filter) // Calling loadContacts methods 

    fileprivate func loadContacts(filter: ContactsFilter) { 
     phoneContacts.removeAll() 
     var allContacts = [PhoneContact]() 
     for contact in PhoneContacts.getContacts(filter: filter) { 
      allContacts.append(PhoneContact(contact: contact)) 
     } 

     var filterdArray = [PhoneContact]() 
     if self.filter == .mail { 
      filterdArray = allContacts.filter({ $0.email.count > 0 }) // getting all email 
     } else if self.filter == .message { 
      filterdArray = allContacts.filter({ $0.phoneNumber.count > 0 }) 
     } else { 
      filterdArray = allContacts 
     } 
     phoneContacts.append(contentsOf: filterdArray) 
     DispatchQueue.main.async { 
      self.tableView.reloadData() 
      } 
     } 
    } 
0

迅速实现4.0在所有联系人的拉动。

let contactStore = CNContactStore() 
var contacts = [CNContact]() 
let keys = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName)] 
let request = CNContactFetchRequest(keysToFetch: keys) 

do { 
    try contactStore.enumerateContacts(with: request) { (contact, stop) in 
     contacts.append(contact) 
    } 
} catch { 
    print(error.localizedDescription) 
} 

这将创建一个本地属性来存储的联系人,然后再通过对contactStore枚举填充。

0

更新斯威夫特4

let contactStore = CNContactStore() 
var contacts = [CNContact]() 
let keys = [ 
     CNContactFormatter.descriptorForRequiredKeys(for: .fullName), 
       CNContactPhoneNumbersKey, 
       CNContactEmailAddressesKey 
     ] as [Any] 
let request = CNContactFetchRequest(keysToFetch: keys as! [CNKeyDescriptor]) 
do { 
    try contactStore.enumerateContacts(with: request){ 
      (contact, stop) in 
     // Array containing all unified contacts from everywhere 
     contacts.append(contact) 
     for phoneNumber in contact.phoneNumbers { 
      if let number = phoneNumber.value as? CNPhoneNumber, let label = phoneNumber.label { 
       let localizedLabel = CNLabeledValue<CNPhoneNumber>.localizedString(forLabel: label) 
       print("\(contact.givenName) \(contact.familyName) tel:\(localizedLabel) -- \(number.stringValue), email: \(contact.emailAddresses)") 
      } 
     } 
    } 
    print(contacts) 
} catch { 
    print("unable to fetch contacts") 
} 
相关问题