select multiple properties from single contact in CNContactPicker
Asked Answered
R

1

0

I am trying to use the CNContactPickerViewController and keep running into issues with how to pick multiple properties from a single contact

Basic display of the picker

    let contactStore = CNContactStore()

override func viewDidLoad() {
    super.viewDidLoad()

    self.askForContactAccess()
    self.displayContacts()
}

func displayContacts(){
    let contactPicker = CNContactPickerViewController()
    contactPicker.delegate = self
    self.present(contactPicker, animated: true, completion: nil)
}

this displays the address book after the user gives permission(the code is there but didn't show it above)

Now what I would like to do is when the user selects a contact we navigate into the contact details view(this happens currently) but when I try to use the delegate

func contactPicker(_ picker: CNContactPickerViewController, didSelectContactProperties contactProperties: [CNContactProperty])

I get presented with the contact picker view where I can select multiple contacts. I don't mind trying to extend the contact detail view so that I can select multiple properties but I don't even know how to hook into it.

I can create a completely custom table view and select the properties there but since apple created a nice contact detail view I would rather use that.

Robustious answered 11/5, 2018 at 1:57 Comment(2)
I think you need to seed the CNContactPickerViewController#displayedPropertyKeys with the properties you want to be displayed before the picker will display the property sheet for a specific contactScarcely
Thanks MadProgrammer - I'm not sure about the propertykeys since I really do want it to display all properties in the contact. Right now when I don't add a delegate function it does display the whole details card..I just can't do anything with it.Robustious
V
2

tl;dr - No, you can't use CNContactPickerViewController to select multiple properties from one contact.

Full version:

CNContactPickerViewController is poorly and confusingly implemented.

It in fact does not actually support the ability to select multiple properties from a single contact. The picker is automatically dismissed after selecting a single contact property.

It does not actually let the user select specific properties from multiple contacts.

It supports the following:

  • Select a single contact
  • Select a single property of a single contact
  • Select multiple contacts
  • Select multiple contacts and return a single predetermined (not user chosen) property from each of the user selected multiple contacts.

To get the didSelectContactProperties delegate to be called with anything other than an empty list of properties, you must set the predicateForSelectionOfProperty property to a predicate that specifies one and only one contact property key. If you provide any other predicate, the get a black screen when you tap on a contact and your app is now hung and needs to be killed.

I believe there are several bugs associated with picking contact properties of multiple contacts.

Workaround:

I believe the only solution (besides your own complete custom view controllers around the Contacts framework) would be to make your own multiple property selection by combining CNContactPickerViewController in single contact selection mode, followed by using CNContactViewController to display the details of the selected contact. Then implement the contactViewController(_:shouldPerformDefaultActionFor:) delegate method to keep track of the properties chosen by the user.

Vladamir answered 11/5, 2018 at 4:18 Comment(3)
Thank you Maddy for a very thorough explanation. I agree it looks like picker seems to be poorly implemented. I did find that by implementing contactPicker.predicateForSelectionOfContact = NSPredicate(value: false) and then using the func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) I could at least click on multiple properties and add them to my array of properties, but I don't see a way to keep the highlight/place a checkbox next to each of the properties since I have no way of actually getting access to the detail viewcontrollerRobustious
Maddy in terms of your workaround...even if I keep it in single contact selection mode when I click a contact it either dismissed the view immediately(if predicateForSelectionOfContact = NSPredicate(value: true) or takes me to the detail view if the predicate is set to false. Do you know of a clean way to actually display the cncontactviewcontroller?Robustious
I haven't actually tried my suggested possible workaround. But I would guess you would have to display the CNContactViewController after the CNContactPickerViewController is dismissed.Vladamir

© 2022 - 2024 — McMap. All rights reserved.