An Easy Way To Use Contact Picker

API for selecting a contact in iOS seems unnecessarily difficult, it becomes a nightmare when you have to use it again and again at different places in your project. I think the idea of delegates is over-used in iOS, and they could have made things much simpler by relying on blocks instead.

So here again, instead of creating delegates again and again, I created a simple wrapper class that encapsulates the ugliness of the API and offers a clean way to the end developer. Here is how I use it in a view controller:

ETPeoplePicker *picker = [[ETPeoplePicker alloc] initWithViewController:self andSuccessBlock:^(NSString *name, NSString *number) {
    NSLog(@"You selected %@", number);
} andFailureBlock:^ {
    
}];
[picker show];

That’s it. Here is the code for ETPeoplePicker:

//
//  ETPeoplePicker.h
//
//  Created by Umar Ashfaq on 5/16/14.
//

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

typedef void(^ETPeoplePickerSuccessBlock)(NSString *name, NSString *number);
typedef void(^ETPeoplePickerFailureBlock)();

@interface ETPeoplePicker : UIView<ABPeoplePickerNavigationControllerDelegate>

-(id)initWithViewController:(UIViewController *)viewController andSuccessBlock:(ETPeoplePickerSuccessBlock)success andFailureBlock:(ETPeoplePickerFailureBlock)failure;

-(void) show;

@end

//
//  ETPeoplePicker.m
//
//  Created by Umar Ashfaq on 5/16/14.
//

#import "ETPeoplePicker.h"
#import "ETUtils.h"
#import <AddressBookUI/AddressBookUI.h>
#import "ETSentItemPreviewViewController.h"

@interface ETPeoplePicker() <ABPeoplePickerNavigationControllerDelegate>

@property(nonatomic, strong) ETPeoplePickerSuccessBlock success;
@property(nonatomic, strong) ETPeoplePickerFailureBlock failure;
@property(nonatomic, strong) UIViewController* viewController;

@end

@implementation ETPeoplePicker

-(id)initWithViewController:(UIViewController *)viewController andSuccessBlock:(ETPeoplePickerSuccessBlock)success andFailureBlock:(ETPeoplePickerFailureBlock)failure
{
    self = [super init];
    
    if ( self )
    {
        _viewController = viewController;
        _success = success;
        _failure = failure;
    }
    
    return self;
}

-(void) show
{
    ABPeoplePickerNavigationController *abPicker = [[ABPeoplePickerNavigationController alloc] init];
    abPicker.peoplePickerDelegate = self;
    abPicker.delegate = (ETSentItemPreviewViewController *) self.viewController;
    [self.viewController presentViewController:abPicker animated:NO completion:nil];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    [peoplePicker dismissViewControllerAnimated:NO completion:nil];
    
    //    recipient = person;
    NSString *recipientName = (__bridge NSString *)(ABRecordCopyCompositeName(person));
    NSString *recipientPhone;
    
    //    recipientPhone = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonPhoneProperty));
    ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
    if ( ABMultiValueGetCount(phoneNumbers) > 0 )
    {
        recipientPhone = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(phoneNumbers, 0));
        recipientPhone = [ETUtils normalizePhoneNumber:recipientPhone];
    }
    CFRelease(phoneNumbers);
    
    NSLog(@"Selected number: %@", recipientPhone);
    self.success(recipientName, recipientPhone);
    
    return NO;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    [peoplePicker dismissViewControllerAnimated:YES completion:nil];
    return NO;
}

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
    [peoplePicker dismissViewControllerAnimated:YES completion:nil];
}

@end

Published by

Umar Ashfaq

Umar Ashfaq is a full-stack web developer. His core strength is building neat UIs with JavaScript on web but he also enjoys server side Java, NodeJS and Objective C. Follow him on twitter @umarashfaq87

Leave a Reply

Your email address will not be published. Required fields are marked *