6

I know how to pick a contact in iOS (using the CNContactPickerViewController), but how can I pick a specific phone number for a contact, instead of the contact itself, as a whole? That should be possible, according to the docs, but I didn't find out how.

EDIT: here's my code

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

contactPicker.delegate = self;
contactPicker.displayedPropertyKeys = @[CNContactGivenNameKey, CNContactImageDataAvailableKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactThumbnailImageDataKey, CNContactIdentifierKey];

[self presentViewController:contactPicker animated:YES completion:nil];

So, I do set the displayedProperties, but the result is the same, even if I choose only CNContactPhoneNumbersKey, I'm not presented with all contact's numbers so that I can choose a speicific number.

What am I missing?

EDIT 2: the callback methods, as requested. I don't know of what significance they are, but nevertheless.

-(void) contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{
  //NSLog(@"Contact : %@",contact);
  NSString* contactName = [NSString stringWithFormat:@"%@%@%@", contact.givenName, @" ", contact.familyName];
  [currentButton setTitle:contactName forState:UIControlStateNormal];
  [currentName setText:contactName];
...
}

-(void) contactPickerDidCancel:(CNContactPickerViewController *)picker {
  //NSLog(@"Cancelled");
}
Eir
  • 1,003
  • 9
  • 24
  • each contact has an array of phone numbers, search through the array to select a specific phone number – MSU_Bulldog Jan 12 '17 at 21:08
  • 1
    Well, I could also search through an array of contacts and select a specific one, but it's much more helpful to have the picker. In Android you can pick a number, and according to the docs, the same goes for iOS too, I read in the docs: "The CNContactPicker object displays the popover-based system interface for selecting a contact. The methods and properties of this class help you choose a contact or a contact's value, such as a phone number or email address, of a contact." – Eir Jan 12 '17 at 22:13

2 Answers2

10

OK, here's the answer:

First of all, use only the property that you want to select in the displayedPropertyKeys (in this case that is CNContactPhoneNumbersKey), and make sure to implement ALL delegate methods (i.e. both didSelectContact - when the contact has only one phone number, and didSelectContactProperty - when the contact has more than one phone number).

Furhtermore, restrict the contact selection by setting:

contactPicker.predicateForEnablingContact = [NSPredicate predicateWithFormat:@"phoneNumbers.@count > 0"];
contactPicker.predicateForSelectionOfContact = [NSPredicate predicateWithFormat:@"phoneNumbers.@count == 1"];
contactPicker.predicateForSelectionOfProperty = [NSPredicate predicateWithFormat:@"key == 'phoneNumbers'"];
jt_uk
  • 1,362
  • 1
  • 15
  • 17
Eir
  • 1,003
  • 9
  • 24
  • Thanks Eir. It still does not work in my case. I have a very simple code here: contactPicker = [[CNContactPickerViewController alloc] init]; [contactPicker setDisplayedPropertyKeys:@[CNContactPhoneNumbersKey]]; and then I do the predicate like you said. But I get an error for the last predicateForSelectionOfProperty that says " Error Domain=CNErrorDomain Code=400 \"Invalid Predicate\" UserInfo={CNKeyPaths=(\n phoneNumber\n), NSLocalizedDescription=Invalid Predicate" I've tried making it phoneNumbers, it still gives me the same error 'Invalid predicate' – Curious101 Feb 15 '17 at 19:07
  • I also tried this predicate with an apostrophe i.e. [NSPredicate predicateWithFormat:@"key == 'phoneNumber'"], with this the Invalid predicate error goes away, but my selection is still not based on property, it is based on contacts. It feels like I must be missing some other piece, I've verified that I have the delegate set properly and am also implementing didSelectContacts and didSelectContactProperties (I want multiple selection). – Curious101 Feb 15 '17 at 19:12
  • What I posted is working code. Maybe you have a typo somewhere? Or you're targeting an old iOS version? – Eir Feb 16 '17 at 10:34
  • @Pankaj - I confirm this code works. (Thanks!) I'm using it to pick the emailAddresses, but I think I've spotted why yours isn't working. Try `contactPicker.predicateForSelectionOfProperty = [NSPredicate predicateWithFormat:@"key == 'phoneNumbers'"];`. The key names are [here](https://developer.apple.com/documentation/contacts/cncontact?language=objc). – jt_uk Nov 18 '17 at 15:20
  • Doesn't work for me, only the pick contact gets called (not the pick property one) and also I can't get it to display the phone numbers. Strange, I know it should work! I am using Swift 4 FYI – Miroslav Kuťák Feb 12 '18 at 15:00
  • Addind to KutakMir's comments, I also can't get this to work. Implemented as show, it locks out any contact with more than one phone number from selection. What I want is for those contacts to display all their numbers and have the user pick one of them and return it. – Andrew Wilcockson Feb 27 '18 at 22:59
0

You need to set the displayedKeys property of the CNContactPicker. If you don't set any keys, you can only select a contact. If you set the keys, then you choose a contact then you select a desired contact property.

Implement the appropriate delegate methods to complete the process.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Thanks for the reply! I am setting the displayedPropertyKeys, but without success. I posted my code, maybe you could spot the problem? – Eir Jan 12 '17 at 22:23
  • 1
    Have you implemented the proper delegate methods? Update your question with the delegate methods you have implemented. BTW - your question states you are using `CNContactPicker` but your code shows you using `CNContactPickerViewController`. – rmaddy Jan 12 '17 at 22:46
  • I posted the implementation of the delegate methods. What's the difference in regard to this problem between using the CNContactPicker and CNContactPickerViewController ? Both claim to have the option to pick a contact property and both take the same arguments. – Eir Jan 13 '17 at 09:46
  • 1
    I completed your answer, in order to mark it as the accepted answer. It was lacking quite a bit, but it was in the right direction. – Eir Feb 09 '17 at 10:36
  • I'm trying to do the same, the accepted answer and the comments are not clear what the solution is. Can you please elaborate? – Curious101 Feb 12 '17 at 23:14
  • @Pankaj I posted the full solution, as my changes to the above answer were rejected. – Eir Feb 15 '17 at 17:56