1. Using the ABUnknownPersonViewController Class
Often, you want to present to
the user a partial record and allow them to use this partial information
to create a new record or add this information to an existing record.
The ABUnknownPersonViewController is used for this purpose. In addition to the AddressBook framework, you will need to add the AddressBookUI framework. Also, don't forget to add the following import statement:
#import <AddressBookUI/AddressBookUI.h>
To use this controller, you first allocate it and initialize it. Next, you set its displayedPerson property to a person record with its relevant properties filled in. After that, you set the delegate property unknownPersonViewDelegate to an object that implements the ABUnknownPersonViewControllerDelegate protocol. If you want the user to change the address book database, you set the allowsAddingToAddressBook property to YES. Finally, you push the controller on the stack.
The delegate needs to implement the method unknownPersonViewController:didResolveToPerson: which is declared as follows:
-(void)unknownPersonViewController:(ABUnknownPersonViewController *)
unknownCardViewController didResolveToPerson:(ABRecordRef)person;
If the user cancelled the controller, person will have the value NULL. Otherwise, you receive the person object with the user's modifications. The person record would have been added to the database by this time. You will need to pop the controller in this method.
Listing 1 shows the method that pushes an ABUnknownPersonViewController
instance and the delegate method that pops it. The delegate method does
not inspect the person returned. Depending on your application, you may
want to use this object. The complete application can be found in the VisuallyAddingContact project available from the source downloads.
Example 1. Utilizing an ABUnknownPersonViewController class to add/modify a person record visually by the user.
-(void)buttonPushed{
ABUnknownPersonViewController *unknownPersonViewController =
[[[ABUnknownPersonViewController alloc] init] autorelease];
ABRecordRef person = ABPersonCreate();
ABRecordSetValue(person, kABPersonFirstNameProperty, @"Barack", NULL);
ABRecordSetValue(person, kABPersonLastNameProperty, @"Obama", NULL);
unknownPersonViewController.displayedPerson = person;
CFRelease(person);
unknownPersonViewController.allowsAddingToAddressBook = YES;
unknownPersonViewController.unknownPersonViewDelegate = self;
[self.navigationController
pushViewController:unknownPersonViewController animated:YES];
}
- (void)unknownPersonViewController:(ABUnknownPersonViewController *)
unknownCardViewController didResolveToPerson:(ABRecordRef)person{
[self.navigationController popViewControllerAnimated:YES];
}
2. Using the ABPeoplePickerNavigationController Class
If you want to ask the user to choose a person record or, say, a phone number from the address book, then the ABPeoplePickerNavigationController class is your friend.
To use this class, you
allocate it, initialize it, set its delegate to an object implementing
its delegate, optionally specifying the properties (emails, phone
numbers, etc.) that should be displayed when the user peeks into a
specific record, and finally present it modally. The following code
fragment shows a people picker that only shows the phone numbers of
records:
ABPeoplePickerNavigationController *peoplePickerViewController =
[[[ABPeoplePickerNavigationController alloc] init] autorelease];
peoplePickerViewController.peoplePickerDelegate = self;
peoplePickerViewController.displayedProperties =
[NSArray arrayWithObject:
[NSNumber numberWithInt:kABPersonPhoneProperty]];
[self presentModalViewController:peoplePickerViewController
animated:YES];
The displayedProperties property uses an array of ABPropertyIDs of the properties you want to show. Notice that we did not push the controller but rather we presented it.
The delegate should implement the following three methods:
- (void)peoplePickerNavigationControllerDidCancel:
(ABPeoplePickerNavigationController *)peoplePicker;
This method is called when the user cancels the operation. You should dismiss the controller as follows:
[self dismissModalViewControllerAnimated:YES];
The second method is the following:
- (BOOL)
peoplePickerNavigationController:(ABPeoplePickerNavigationController *)
peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person;
This method is called when
the user selects a person record wanting to see its details or
confirming that this is the record they are interested in. Depending on
the purpose of the people picker, you should either return YES to allow showing of the selected properties, or return NO and dismiss the controller as above.
Finally, the following method is called when the user selects a specific property (see Figure 1):
- (BOOL)
peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier;
If you want the default action to be performed (e.g., dialing a phone number), you should return YES
and possibly dismiss the controller. If, on the other hand, you're just
interested in the value the user has selected, you should return NO and dismiss the controller.
The method is passed the person record and the value identifier in a multi-value property that was selected. For example, if you show phone numbers, and the person record contains three phone numbers, you get to know which of these phone numbers was selected (by its unique identifier).
The following shows a possible implementation.
ABMultiValueRef phoneProperty = ABRecordCopyValue(person, property);
NSInteger phoneIndex =
ABMultiValueGetIndexForIdentifier(phoneProperty, identifier);
NSString *phone =
(NSString *)ABMultiValueCopyValueAtIndex(phoneProperty, phoneIndex);
NSLog(@"The phone number selected is %@:", phone);
CFRelease(phoneProperty);
[phone release];
[self dismissModalViewControllerAnimated:YES];
return NO;
In the above method, we
retrieve the value of the property. Since this property is multi-value,
we retrieve its index. After that, we retrieve the value chosen by the
user using this index. We release memory, as we have learned before, and
dismiss the controller.
The project PersonPicker, available from the source downloads, contains a complete application using the people picker.