CNContactPickerViewController issues

So moving from Address book to Contacts, and watching the video https://developer.apple.com/videos/wwdc/2015/?id=223

I found a few things missing.


I just want to display my contacts that have one or more email addresses. So I use:


        let contactPicker = CNContactPickerViewController()
        contactPicker.displayedPropertyKeys = [CNContactEmailAddressesKey]

        contactPicker.predicateForEnablingContact = NSPredicate(format: "emailAddresses.@count > 0")
        contactPicker.predicateForSelectionOfContact = NSPredicate(format: "emailAddresses.@count == 1")

        contactPicker.delegate = self

        self.presentViewController(contactPicker, animated: true, completion: nil)


First in the video they do not show but I'm assuming we have to impliment the CNContactPickerDelegate.


Next I have the following method to catch the selection of the contact email:


func contactPicker(picker: CNContactPickerViewController, didSelectContactProperty contactProperty: CNContactProperty) {
        print(contactProperty.contact)
    }


When the Contacts are initially displayed, I get this

#1

2015-07-25 13:42:12.448 [1327:453453] [CNUI ERROR] Person selection predicate is set but the delegate does not implement contactPicker:didSelectContact:. The predicate will be ignored.

Not sure why.


The real question is when I select one of the emails in the contact card, the device goes blank and in the log I get:


#2

2015-07-25 13:44:10.521 [1327:454336] plugin com.apple.MobileAddressBook.ContactsViewService interrupted

2015-07-25 13:44:10.523 [1327:454336] plugin com.apple.MobileAddressBook.ContactsViewService invalidated

2015-07-25 13:44:10.540 [1327:453453] viewServiceDidTerminateWithError:: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)" UserInfo={Message=Service Connection Interrupted}

Accepted Reply

You're not doing anything wrong. There is a bug in the iOS 9 beta. You are seeing the symptom of that bug. I reported it - bug # 21569949; it has been closed as a duplicate of bug # 21165461, which is still open.


EDIT: My workaround has been to throw together a quick TableViewController that I fill in myself (with the phone #s for example), show that, and take appropriate action when the user selects a row in the table. I'm hoping the bug will be fixed before general release.

Replies

There's no point showing the detail screen for a contact who only has one email so you have (correctly) used predicateForSelectionOfContact to indicate that you want to be told when a contact with one email is picked. As the error message said, this means you need to implement contactPicker:didSelectContact: That method is used to report when a contact is picked.


If a contact has more than one email, a detail page will be shown and if the user chooses one of the emails (i.e. one of the properties), then contactPicker:didSelectContactProperty: is called.

Thats my point. I am selecting a contact that has 2 emails. The detail page is shown and if I click on one of the emails, I get the error. As you can see I implimented the contactPicker:didSelectContactProperty. Thoughts? (I've also implimented the didSelectContact and it never gets called)

So I found that the ContactsPicker I was calling was in the wrong module, so I fixed that and no longer get the "must contactPicker:didSelectContact" message.


However when I select and email from the contact detail page I now get:


2015-07-27 09:38:11.421 [35106:3864914] plugin com.apple.MobileAddressBook.ContactsViewService interrupted

2015-07-27 09:38:11.422 [35106:3864914] plugin com.apple.MobileAddressBook.ContactsViewService invalidated

2015-07-27 09:38:11.422 [35106:3864844] viewServiceDidTerminateWithError:: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)" UserInfo={Message=Service Connection Interrupted}

I think this may be a regression in beta 4. I have similar code in one of my apps (but I'm using phone numbers, not emails) and it used to work.


I just tried with Xcode 7 beta 4 and it gives the same error you reported on both a real device (also beta 4) and the simulator. The same code built in Xcode 7 beta 3 fails on my real device, but works in the (beta 3) simulator.


So, it's not just you! Please report the bug to Apple.

22012485 has been submited

I finally found a workaround! Although the documention states that CNContactPickerViewController does not require permissions, the only way I could make it work since iOS 9 Beta 4 is to request permission to Contacts before (in viewDidLoad):


let cn = CNContactStore()
cn.requestAccessForEntityType(CNEntityType.Contacts) { (success: Bool, error: NSError?) -> Void in }


It also requires Info.plist to contain the key "NSContactsUsageDescription" with a string explaining the reason for this permission.

Any luck resolving this?


I have an issue with CNContactPickerViewController as well.


This is my code:

- (void)openContactPicker

{

if(GetIphoneCallback()->IsOS9())

{

CNContactPickerViewController *picker = [[CNContactPickerViewController alloc] init];

NSPredicate *EnablePredicate = [NSPredicate predicateWithFormat:@"postalAddresses.@count > 0"];

picker.predicateForEnablingContact = EnablePredicate;

NSPredicate *SelectionPredicate = [NSPredicate predicateWithFormat:@"postalAddresses.@count == 1"];

picker.predicateForSelectionOfContact = SelectionPredicate;

picker.delegate = self;

GetIphoneCallback()->PresentViewController(picker, true, &m_contactEvent);

[picker release];

}

else

{

ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];

picker.peoplePickerDelegate = self;

GetIphoneCallback()->PresentViewController(picker, true, &m_contactEvent);

[picker release];

}

}


- (void)contactPicker:(CNContactPickerViewController *)picker

didSelectContactProperty:(CNContactProperty *)contactProperty

{

...

}


-(void)contactPicker:(CNContactPickerViewController *)picker

didSelectContact:(CNContact *)contact

{

....

}

I have setup the delegate for the controller and I present it. It does show the contacts. And I'm able to click the contacts.

I have a predicate for the selection of contacts. So if I click a contact which has only one postal address then it calls the didSelectContact or it displays the contact properties where it lists out all the addresses for that contact. So this works fine.


The problem is when it displays the properties and I click an address it does not call the didSelectContactProperty method. Instead the display goes blank with this error message.

2015-08-11 10:47:55.015 CoPilot_NA_MapViewer[292:17453] plugin com.apple.MobileAddressBook.ContactsViewService interrupted

2015-08-11 10:47:55.018 CoPilot_NA_MapViewer[292:17431] plugin com.apple.MobileAddressBook.ContactsViewService invalidated

2015-08-11 10:47:55.031 CoPilot_NA_MapViewer[292:17330] viewServiceDidTerminateWithError:: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)" UserInfo={Message=Service Connection Interrupted}


I have implemented the didSelectContactProperty method the same way I have implemented the didSelectContact.


What am I doing wrong?

You're not doing anything wrong. There is a bug in the iOS 9 beta. You are seeing the symptom of that bug. I reported it - bug # 21569949; it has been closed as a duplicate of bug # 21165461, which is still open.


EDIT: My workaround has been to throw together a quick TableViewController that I fill in myself (with the phone #s for example), show that, and take appropriate action when the user selects a row in the table. I'm hoping the bug will be fixed before general release.

Thank you for your reply. Let's hope they fix it soon.

The fix described by @arytbk worked for me however it only works on a device and fails on a simulator


Codger


Thanks Arytbk

I've observed that this issue remains unresolved in Xcode 7 Beta 6 (7A192o).


Johnnieb

Delegate working now in GM


Codger