官方文档 Address Book Programming Guide
Introduction
1. The technology has several parts:
- The Address Book framework provides access to the contact information.
- The Address Book UI framework provides the user interface to display the information.
- The Address Book database stores the information.
- The Contacts application provides a way for users to access their contact information.
Records and Properties
1. Address Books
(1) To use an address book, declare an instance of ABAddressBookRef and set it to the value returned from the function ABAddressBook. You can create multiple address book objects, but they are all backed by the same shared database.
ABAddressBookRef addressBook;
bool wantToSaveChanges = YES;
bool didSave;
CFErrorRef error = NULL;
addressBook = ABAddressBookCreate();
/* ... Work with the address book. ... */
if (ABAddressBookHasUnsavedChanges(addressBook)) {
if (wantToSaveChanges) {
didSave = ABAddressBookSave(addressBook, &error);
if (!didSave) {/* Handle error here. */}
} else {
ABAddressBookRevert(addressBook);
}
}
CFRelease(addressBook);
(2) Your application can request to receive a notification when Address Book database changes.
Use the function ABAddressBookRegisterExternalChangeCallback to register a function of the prototypeABExternalChangeCallback.You can also unregister the function using ABAddressBookUnregisterExternalChangeCallback.
2. Records
(1) In the Address Book database, information is stored in records, represented byABRecordRef objects. Each record represents a person or group. The functionABRecordGetRecordType returns kABPersonType if the record is a person, and kABGroupType if it is a group.
ABRecordRef person = ABPersonCreate();
ABRecordCopyValue
ABRecordSetValue
ABRecordRemoveValue
(2) Person records are made up of both single-value and multi-value properties.
(3) Single Value Property
ABRecordRef aRecord = ABPersonCreate();
CFErrorRef anError = NULL;
bool didSet;
didSet = ABRecordSetValue(aRecord, kABPersonFirstNameProperty, CFSTR("Katie"), &anError);
if (!didSet) {/* Handle error here. */}
didSet = ABRecordSetValue(aRecord, kABPersonLastNameProperty, CFSTR("Bell"), &anError);
if (!didSet) {/* Handle error here. */}
CFStringRef firstName, lastName;
firstName = ABRecordCopyValue(aRecord, kABPersonFirstNameProperty);
lastName = ABRecordCopyValue(aRecord, kABPersonLastNameProperty);
/* ... Do something with firstName and lastName. ... */
CFRelease(aRecord);
CFRelease(firstName);
CFRelease(lastName);
(4) Multi Value Property
ABMutableMultiValueRef multi =
ABMultiValueCreateMutable(kABMultiStringPropertyType);
CFErrorRef anError = NULL;
ABMultiValueIdentifier multivalueIdentifier;
bool didAdd, didSet;
// Here, multivalueIdentifier is just for illustration purposes; it isn't
// used later in the listing. Real-world code can use this identifier to
// reference the newly-added value.
didAdd = ABMultiValueAddValueAndLabel(multi, @"(555) 555-1234",
kABPersonPhoneMobileLabel, &multivalueIdentifier);
if (!didAdd) {/* Handle error here. */}
didAdd = ABMultiValueAddValueAndLabel(multi, @"(555) 555-2345",
kABPersonPhoneMainLabel, &multivalueIdentifier);
if (!didAdd) {/* Handle error here. */}
ABRecordRef aRecord = ABPersonCreate();
didSet = ABRecordSetValue(aRecord, kABPersonPhoneProperty, multi, &anError);
if (!didSet) {/* Handle error here. */}
CFRelease(multi);
/* ... */
CFStringRef phoneNumber, phoneNumberLabel;
multi = ABRecordCopyValue(aRecord, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) {
phoneNumberLabel = ABMultiValueCopyLabelAtIndex(multi, i);
phoneNumber = ABMultiValueCopyValueAtIndex(multi, i);
/* ... Do something with phoneNumberLabel and phoneNumber. ... */
CFRelease(phoneNumberLabel);
CFRelease(phoneNumber);
}
CFRelease(aRecord);
CFRelease(multi);
Multi value properties consist of a list of values. Each value has a text label and an identifier associated with it. There can be more than one value with the same label, but the identifier is always unique.
The individual values of a multivalue property are referred to by identifier or by index, depending on the context. Use the functionsABMultiValueGetIndexForIdentifier and ABMultiValueGetIdentifierAtIndex to convert between indices and multivalue identifiers.
The index will change if values are added or removed. The identifier is guaranteed not to change except across devices.
Multivalue objects are immutable; to change one you need to make a mutable copy using the functionABMultiValueCreateMutableCopy. You can also create a new mutable multivalue object using the functionABMultiValueCreateMutable.
The following functions let you modify mutable multivalue properties:
- ABMultiValueAddValueAndLabel and ABMultiValueInsertValueAndLabelAtIndex add values.
- ABMultiValueReplaceValueAtIndex and ABMultiValueReplaceLabelAtIndex change values.
- ABMultiValueRemoveValueAndLabelAtIndex removes values.
User Interface
(1) The Address Book UI framework provides three view controllers and one navigation controller for common tasks related to working with the Address Book database and contact information.
- ABPeoplePickerNavigationController prompts the user to select a person record from their address book.
- ABPersonViewController displays a person record to the user and optionally allows editing.
- ABNewPersonViewController prompts the user create a new person record.
- ABUnknownPersonViewController prompts the user to complete a partial person record, optionally allows them to add it to the address book.
ABPeoplePickerNavigationController *picker =
[[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentModalViewController:picker animated:YES];
[picker release];
Optionally, set displayedProperties to the array of properties you want displayed. The relevant constants are defined as integers; wrap them in anNSNumber object using the numberWithInt: method to get an object that can be put in an array.
- If the user cancels, the people picker calls the methodpeoplePickerNavigationControllerDidCancel: of the delegate, which should dismiss the people picker.
- If the user selects a person, the people picker calls the methodpeoplePickerNavigationController:shouldContinueAfterSelectingPerson: of the delegate to determine if the people picker should continue. To prompt the user to choose a specific property of the selected person, returnYES. Otherwise return NO and dismiss the picker.
- If the user selects a property, the people picker calls the methodpeoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier: of the delegate to determine if it should continue. To perform the default action (dialing a phone number, starting a new email, etc.) for the selected property, returnYES. Otherwise returnNO and dismiss the picker using thedismissModalViewControllerAnimated: method. It is recommended that you dismiss it using animation..
(3) ABPersonViewController
ABPersonViewController *view = [[ABPersonViewController alloc] init];
view.personViewDelegate = self;
view.displayedPerson = person; // Assume person is already defined.
[self.navigationController pushViewController:view animated:YES];
[view release];
If the user taps on a property in the view, the person view controller calls thepersonViewController:shouldPerformDefaultActionForPerson:property:identifier: method of the delegate to determine if the default action for that property should be taken. To perform the default action for the selected property, such as dialing a phone number or composing a new email, returnYES; otherwise returnNO.
(4) ABNewPersonViewController
ABNewPersonViewController *view = [[ABNewPersonViewController alloc] init];
view.newPersonViewDelegate = self;
UINavigationController *newNavigationController = [[UINavigationController alloc]
initWithRootViewController:view];
[self presentModalViewController:newNavigationController
animated:YES];
[view release];
[newNavigationController release];
When the user taps the Save or Cancel button, the new-person view controller calls the methodnewPersonViewController:didCompleteWithNewPerson: of the delegate, with the resulting person record. If the user saved, the new record is first added to the address book. If the user cancelled, the value ofperson isNULL. The delegate must dismiss the new-person view controller using the navigation controller’sdismissModalViewControllerAnimated: method.
(5) ABUnknownPersonViewController
ABUnknownPersonViewController *view = [[ABUnknownPersonViewController alloc] init];
view.unknownPersonViewDelegate = self;
view.displayedPerson = person; // Assume person is already defined.
view.allowsAddingToAddressBook = YES;
[self.navigationController pushViewController:view animated:YES];
[view release];
When the user finishes creating a new contact or adding the properties to an existing contact, the unknown-person view controller calls the methodunknownPersonViewController:didResolveToPerson: of the delegate with the resulting person record. If the user canceled, the value ofperson isNULL.
Programmatically Accessing the Database
1. Record
To get the record identifier of a record, use the functionABRecordGetRecordID. To find a person record by identifier, use the functionABAddressBookGetPersonWithRecordID. To find a group by identifier, use the functionABAddressBookGetGroupWithRecordID. To find a person record by name, use the functionABAddressBookCopyPeopleWithName.
2. Working with person records
You can add and remove records from the Address Book database using the functionsABAddressBookAddRecord and ABAddressBookRemoveRecord.
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(
kCFAllocatorDefault,
CFArrayGetCount(people),
people
);
CFArraySortValues(
peopleMutable,
CFRangeMake(0, CFArrayGetCount(peopleMutable)),
(CFComparatorFunction) ABPersonComparePeopleByName,
(void*) ABPersonGetSortOrdering()
);
CFRelease(addressBook);
CFRelease(people);
CFRelease(peopleMutable);