1

I am trying to retrieve all contacts and save them in VCard form (swift 4, XCode 9.0). But CNContactVCardSerialization.data(with:) always returns nil. Here is my code:

    var contacts = [CNContact]()
    let request = CNContactFetchRequest(keysToFetch:[CNContact.descriptorForAllComparatorKeys()])
    do {
        try contactsStore.enumerateContacts(with: request,  usingBlock:
        { (contact:CNContact, result:UnsafeMutablePointer<ObjCBool>) in
            self.contacts.append(contact)
        })
    }
    catch {
    }

    // at this point all contacts are in the "contacts" array.

    var data = Data()
    do {
        try data = CNContactVCardSerialization.data(with: contacts)
    }
    catch {
        print("some error in contacts:" + String(describing: error));
    }
    print(">>>data:" + String(data.count))

Output:

  2017-11-02 XXX [5224:449081] 
  Exception writing contacts to vCard (data): A property was not 
  requested when contact was fetched.
  2017-11-02 XXX [5224:449362] XPC 
  connection interrupted
  some error in contacts:nilError
  >>>data:0

I red the question below but it does not help. How to use method dataWithContacts in CNContactVCardSerialization?

I added "Privacy - Contacts Usage Description" into info.plist

Alex
  • 751
  • 1
  • 9
  • 28

2 Answers2

1

Maybe you need to provide some specific keys to fetch?

UPD: Yep, if you want to fetch requests and serialize them, you have to set keys to fetch: keysToFetch:@[[CNContactVCardSerialization descriptorForRequiredKeys]]

Eugene Biryukov
  • 1,702
  • 1
  • 13
  • 19
  • 1
    Thanks for figuring this out. Total craziness, if this is required, why not throw an error that tells us the problem?! All you get back is nilError. Angry face. – rob5408 May 02 '18 at 01:56
0

Change

let request = CNContactFetchRequest(keysToFetch:[CNContact.descriptorForAllComparatorKeys()])

To

let request = CNContactFetchRequest(keysToFetch:[CNContactVCardSerialization.descriptorForRequiredKeys()])
Tran Trung Hieu
  • 191
  • 2
  • 5