Reputation: 9773
I am trying to share a CNContact between users in my app.
At the moment I'm using a CNContactFetchRequest to fetch the contacts and the user will select one to send.
But I need to define the keys using this request. I want to share the entire contact. Is that possible? I tried omitting the keys argument in the fetch request to get all keys but it threw an error ('init()' is unavailable).
Using this fetch method below I need to recreate the contact and all the fields which is quite a bit of work. I want to serialize the CNContact object and send the data to another app but can't figure out how to do that.
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactOrganizationNameKey, CNContactPhoneNumbersKey, CNContactEmailAddressesKey, CNContactPostalAddressesKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
do {
try store.enumerateContacts(with: request, usingBlock: { (contact, stopPointer) in
self.contacts.append(Contact(firstName: contact.givenName, lastName: contact.familyName, company: contact.organizationName, phoneNumbers: contact.phoneNumbers.map { $0.value.stringValue }, emailAddresses: contact.emailAddresses.map { $0.value as String }, postalAddresses: contact.postalAddresses.map { formatter.string(from: $0.value) }
))
})
} catch let error {
print("Failed to enumerate contact", error)
}
Upvotes: 2
Views: 822
Reputation: 6861
Yes, it's possible. I made this implementation for this goal. I created an enum with all keys.
enum CNContactKeys {
static let keysToFetch: [CNKeyDescriptor] = {
[CNContactIdentifierKey, CNContactTypeKey, CNContactPropertyAttribute,
CNContactNamePrefixKey, CNContactGivenNameKey, CNContactMiddleNameKey,
CNContactFamilyNameKey, CNContactPreviousFamilyNameKey, CNContactNameSuffixKey,
CNContactNicknameKey, CNContactPhoneticGivenNameKey, CNContactPhoneticMiddleNameKey,
CNContactPhoneticFamilyNameKey, CNContactJobTitleKey, CNContactDepartmentNameKey,
CNContactOrganizationNameKey, CNContactPhoneticOrganizationNameKey, CNContactPostalAddressesKey,
CNContactEmailAddressesKey, CNContactUrlAddressesKey, CNContactInstantMessageAddressesKey,
CNContactPhoneNumbersKey, CNContactSocialProfilesKey, CNContactBirthdayKey, CNContactDatesKey,
CNContactImageDataKey, CNContactThumbnailImageDataKey, CNContactImageDataAvailableKey,
CNContactRelationsKey, CNGroupNameKey, CNGroupIdentifierKey, CNContainerNameKey,
CNContainerTypeKey, CNInstantMessageAddressServiceKey, CNInstantMessageAddressUsernameKey,
CNSocialProfileServiceKey, CNSocialProfileURLStringKey, CNSocialProfileUsernameKey,
CNSocialProfileUserIdentifierKey,
CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactFormatter.descriptorForRequiredKeys(for: .phoneticFullName)] as? [CNKeyDescriptor] ?? []
}()
}
Then I used keys array in a function.
func fetchContacts(_ sortOrder: CNContactSortOrder = .userDefault) async throws -> [CNContact] {
var contacts = [CNContact]()
let fetchRequest = CNContactFetchRequest(keysToFetch: CNContactKeys.keysToFetch)
fetchRequest.sortOrder = sortOrder
do {
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
contacts.append(contact)
}
return contacts
} catch {
throw error
}
}
Upvotes: 1