5

I have a subclass of ABPeoplePickerNavigationController to handle selecting a contact phone number in my app. Everything works great on iOS 7 and below.

On iOS 8, however, my ABPeoplePickerNavigationControllerDelegate does not get hit when selecting a phone number. Instead, it just calls that phone number.

I noticed that the method I was using to handle contact selection in iOS 7 (peoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier:) was deprecated in iOS 8. This method was replaced by peoplePickerNavigationController:didSelectPerson:property:identifier:.

I know my delegate is set because I successfully receive the peoplePickerNavigationControllerDidCancel: method callback.

Has anyone else experienced this issue?

Here's a code snippet of my ABPeoplePickerNavigationController subclass:

- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {

    [self peoplePickerNavigationController:peoplePicker shouldContinueAfterSelectingPerson:person property:property identifier:identifier];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {

    ...do stuff...

    return NO;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {

    return YES;
}

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {

    [self dismissViewControllerAnimated:self.shouldAnimateDismiss completion:NULL];
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
Alexander
  • 565
  • 9
  • 20
  • What have you specified `predicateForSelectionOfProperty`? – Rob Sep 24 '14 at 19:19
  • Are you building with Xcode 6 and does your project have a Base SDK of iOS 8? – rmaddy Sep 24 '14 at 19:20
  • @Rob Nothing. It has always worked without setting that. – Alexander Sep 24 '14 at 19:21
  • @rmaddy yes, and yes. – Alexander Sep 24 '14 at 19:22
  • 1
    OK. In iOS 8, `predicateForSelectionOfProperty` affects this behavior, too, so I had to ask. Anyway, have you confirmed (with breakpoints or log statements) that these delegate methods are getting called at all? E.g. that `peoplePickerDelegate` (note, not `delegate`) was correctly specified? – Rob Sep 24 '14 at 19:23
  • And the code from your question was actually copy and pasted from your real code? Just making sure your real code doesn't have some tiny typo in the name of the delegate method. – rmaddy Sep 24 '14 at 19:23
  • @rmaddy Yes, except for the part that says "do stuff..." obviously. – Alexander Sep 24 '14 at 19:26
  • @Rob Yep, I even mentioned in the question that my cancel delegate method gets hit. Then I have breakpoints on my selection methods, and I've verified that they are never hit. – Alexander Sep 24 '14 at 19:27

4 Answers4

6

Where are you specifying the peoplePickerDelegate?

In iOS 8, if you specify peoplePickerDelegate in viewDidLoad, you will experience the curious behavior you describe (cancel delegate works, the didSelect... and shouldContinue... do not). If you specify peoplePickerDelegate immediately after init (or during), it works fine.

This would appear to be an iOS 8 "feature". I'll file a bug report.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • That was my issue. Thanks!! This is a very curious change indeed. – Alexander Sep 24 '14 at 20:50
  • My problem was I was specifying `picker.delegate = self` instead of `picker.peoplePickerDelegate = self`. – kev Nov 04 '14 at 16:35
  • @Rob Hello sir i am doing all fine in my project i specify peoplePickerDelegate on button click method, but now cancel method works fine but (BOOL)peoplepickernavigationcontroller not called. – sandeep tomar Jan 22 '16 at 09:18
2

above two delegate methods are deprecated in ios 8.0, use use methods last two for getting your desire result

above two delegate methods are deprecated in iOS 8.0, use last two methods for getting your desire result

this is apple developer guideline link give you more information about

ABPeoplePickerNavigationControllerDelegate

mohitdream4u
  • 166
  • 10
0

Nothing would happen when I selected a contact in IOS8.

I found that in addition to

if ([picker respondsToSelector:@selector(setPredicateForSelectionOfPerson:)]) 
    {
         picker.predicateForSelectionOfPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count = 1"];
    }

I also needed

if ([picker respondsToSelector:@selector(setPredicateForEnablingPerson:)])
    {
        picker.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count > 0"];
    }

Source https://developer.apple.com/library/prerelease/ios/samplecode/PeoplePicker/Listings/PeoplePicker_AAPL_8or7_EmailPickerViewController_m.html

Peter Johnson
  • 3,764
  • 1
  • 23
  • 27
0

If you wanna just get person's name you can do this :

-(IBAction)btnGetContact{
    ABPeoplePickerNavigationController *personPicker = [ABPeoplePickerNavigationController new];
    personPicker.peoplePickerDelegate = self;
    [self presentViewController:personPicker animated:YES completion:nil];
}

-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{
        NSString *firstName;
    NSString *middleName;
    NSString *lastName;
    UIImage *retrievedImage;

    // get the first name
    firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);

    //get the middle name
    middleName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonMiddleNameProperty);

    // get the last name
    lastName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

    // get personPicture
    if (person != nil && ABPersonHasImageData(person))
    {
        retrievedImage = [UIImage imageWithData:(__bridge_transfer NSData*)ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail)];
    }
    else
    {
        retrievedImage = nil;
    }
}

But if you are looking to go to person's detail to get person's numbers, you should use BOOL instead void for peoplePickerNavigationController and pass YES like below :

-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{
    return YES;
}



 -(void) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
        ABMutableMultiValueRef phoneno  = ABRecordCopyValue(person, kABPersonPhoneProperty);

CFStringRef phone = ABMultiValueCopyValueAtIndex(phoneno, identifier);

        _mPhone.text = (__bridge NSString *)phone;

        [self dismissViewControllerAnimated:NO completion:^(){}];
    }

Also dont forget to import AddressBook.framework and AddressBookUI.framework to your project and ABPeoplePickerNavigationControllerDelegate ,

#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>

to your header file.

Rudi
  • 4,304
  • 4
  • 34
  • 44