The interface for accessing the address book and a single contact data is a C-language function that transmits references to various objects in the address book as parameters. The base class object for managing entries in the address book is abrecord. An abrecord can represent a person or a group of abgroups. Whenever you select a record on the interface or use the Framework to query and return a result, the system returns a pointer to abrecord, marked as abrecordref. Most of the interactions with the address book API involve the reference type abrecordref.
Common Access record functions are as follows:
Abrecordid abrecordgetrecord (abrecordref record );
The returned abrecordid indicates the ID of the record in the underlying database. It is unique.
Abrecordtype abrecordgetrecordtype (abrecordref record );
Type of the returned record. It can be kabpersontype and kabgrouptype.
Cfstringref abrecordcopycompositename (abrecordref record );
Returns the complete name of an individual or a group. Example: nsstring * name = (nsstring *) abrecordcopycompositename (record );
I. High-level Address Book Functions
1. Get the address book handle
You must initialize the address book before you can perform read/write operations on it. To obtain an address book handle, you can use the abaddressbookcreate function:
#import <AddressBook/AddressBook.h>AddressBookRef ab = AddressBookCreate();
2. Save the address book
After obtaining the address book reference, you can perform operations on it. After the operation is complete, remember to save:
CFErrorRef err;BOOL success = ABAddressBookSave(ab, &err);
If you are not sure whether to save it, you can use:
BOOL hasUnsavedChanges = ABAddressBookHasUnsavedChanges(ab);
3. Add/delete records
Cferrorref err; bool success = abaddressbookaddrecord (AB, record, & ERR); // Add
Cferrorref err; bool success = abaddressbookremoverecord (AB, record, & ERR); // Delete
Ii. query the address book
The address book framework only provides basic query functions. You can use a function to query multiple records by name or a single record by specific record ID.
1. Get the total number of records in the address book:
CFIndex count = ABAddressBookGetPersonCount(ab); printf("%ld total entries in the address book\n",count);
2. Get all contacts:
NSArray* array = (NSArray*)ABAddressBookCopyArrayOfAllPeople(ab); printf("Retrieved %d contacts\n",[array count]);
3. query a specific name in the contact list:
NSArray* arrayByName = (NSArray*)ABAddressBookCopyPeopleWithName(ab, CFSTR("Liu Wei"));
If the function is its name, it returns a copy instead of an actual object in the address book. To access a single record of this array, use the nsarray method:
ABRecordRef myRecord = [arrayByName objectAtIndex:0];
In addition to querying by name, you can also query by ID directly (if you know the ID ):
ABRecordRef myRecord = ABAddressBookGetPersonWithRecordID(ab, recordID);
3. Create records
You can use the abpersoncreate function to create a new contact. In this way, an empty record can be obtained, and information can be filled with it:
ABRecordRef record = ABPersonCreate();
Iv. Operation Records
Once abrecordref is obtained, you can determine whether it is an individual or a group, and then you can access further information. You can use the corresponding attributes to manipulate the name and other information. Only abperson OBJECT records have attributes, and each record has various types of information.
You can use the abrecordcopyvalue function to query the information of a given record. The function is prototype as follows:
CFTypeRef ABRecordCopyValue(ABRecordRef record,kABPersonFirstNameProperty);
When this function is called, a copy of the attribute you specified will be copied and the reference will be returned:
CFStringRef firstName = ABRecordCopyValue(record, kABPersonFirstNameProperty);
Because the kabpersonfirstnameproperty is a cfstring, you can convert it to nsstring *:
NSString* firstName =NSString* ABRecordCopyValue(record, kABPersonFirstNameProperty);
Just as cfstringref can be converted to nsstring *, if the returned type of an attribute is cfdateref, you can also convert it to nsdate *:
NSDate* birthday = (NSDate*) ABRecordCopyValue(record, kABPersonBirthdayProperty);
The abpropertyid specified above is a value corresponding to the information found in the record. Return abperson based on this value
Object Property. Because the data type returned by the abrecordcopyvalue function is cftyperef, the suspicious result is converted to a more refined data type that corresponds to the attribute, as shown in the following table:
// Property keys
extern const ABPropertyID kABPersonFirstNameProperty; // First name - kABStringPropertyType
extern const ABPropertyID kABPersonLastNameProperty; // Last name - kABStringPropertyType
extern const ABPropertyID kABPersonMiddleNameProperty; // Middle name - kABStringPropertyType
extern const ABPropertyID kABPersonPrefixProperty; // Prefix ("Sir" "Duke" "General") - kABStringPropertyType
extern const ABPropertyID kABPersonSuffixProperty; // Suffix ("Jr." "Sr." "III") - kABStringPropertyType
extern const ABPropertyID kABPersonNicknameProperty; // Nickname - kABStringPropertyType
extern const ABPropertyID kABPersonFirstNamePhoneticProperty; // First name Phonetic - kABStringPropertyType
extern const ABPropertyID kABPersonLastNamePhoneticProperty; // Last name Phonetic - kABStringPropertyType
extern const ABPropertyID kABPersonMiddleNamePhoneticProperty; // Middle name Phonetic - kABStringPropertyType
extern const ABPropertyID kABPersonOrganizationProperty; // Company name - kABStringPropertyType
extern const ABPropertyID kABPersonJobTitleProperty; // Job Title - kABStringPropertyType
extern const ABPropertyID kABPersonDepartmentProperty; // Department name - kABStringPropertyType
extern const ABPropertyID kABPersonEmailProperty; // Email(s) - kABMultiStringPropertyType
extern const ABPropertyID kABPersonBirthdayProperty; // Birthday associated with this person - kABDateTimePropertyType
extern const ABPropertyID kABPersonNoteProperty; // Note - kABStringPropertyType
extern const ABPropertyID kABPersonCreationDateProperty; // Creation Date (when first saved)
extern const ABPropertyID kABPersonModificationDateProperty; // Last saved date
5. Write attributes
Write attributes to the record. Use the abrecordsetvalue function:
CFStringRef name = CFSTR("IUKEY");
BOOL suc = ABRecordSetValue(record, kABPersonNicknameProperty, name, &err);
if (suc) {
NSLog(@"setValue succeed");
}
Delete attributes:
BOOL succeed = ABRecordRemoveValue(record, kABPersonFirstNameProperty, &err);
Do not forget to save the address book after modification.
Vi. multi-value Attributes
In addition to the attributes listed above, a record may have some attributes, including multiple values. Multiple attributes can be processed using an index mechanism. When used, you first query the total number of values and then obtain an entry through a specific index. The pointer to multi-value data can be obtained through the abrecordcopyvalue method mentioned earlier, and then converted to multivalueref:
ABMultiValueRef phoneNumbers = ABRecordCopyValue(record, kABPersonPhoneProperty);
Then you can use this reference to determine the number of values and obtain a single value based on the index. The abmultigetcount function returns the number of entries. You can use the abmultivaluecopyvalueatindex function to copy specified entries according to the index.
The entries in the multi-value attribute are listed below:
extern const ABPropertyID kABPersonEmailProperty;
extern const ABPropertyID kABPersonAddressProperty;
extern const ABPropertyID kABPersonDateProperty;
extern const ABPropertyID kABPersonPhoneProperty;
extern const ABPropertyID kABPersonInstantMessageProperty;
extern const ABPropertyID kABPersonURLProperty;
In addition to the true values in the multi-value attribute, each entry also has a tag. Label describes the type of the returned entry. For example, a phone number mark indicates whether the phone number is a home phone number or a mobile phone number. The address label can describe whether it is a home address or a work address. To query specific entry tags, you can use the abmultvaluecopylabelatindex function:
CFStringRef label = ABMultiValueCopyLabelAtIndex(phoneNumbers, i);
Write attributes have a set of predefined tags. The following cfstringref type labels are prototype specified in abperson. h:
extern const ABPropertyID kABPersonDateProperty; // Dates associated with this person - kABMultiDatePropertyType
extern const CFStringRef kABPersonAnniversaryLabel;
// Phone numbers
extern const ABPropertyID kABPersonPhoneProperty; // Generic phone number - kABMultiStringPropertyType
extern const CFStringRef kABPersonPhoneMobileLabel;
extern const CFStringRef kABPersonPhoneIPhoneLabel __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
extern const CFStringRef kABPersonPhoneMainLabel;
extern const CFStringRef kABPersonPhoneHomeFAXLabel;
extern const CFStringRef kABPersonPhoneWorkFAXLabel;
extern const CFStringRef kABPersonPhoneOtherFAXLabel __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);
extern const CFStringRef kABPersonPhonePagerLabel;
// IM
extern const ABPropertyID kABPersonInstantMessageProperty; // Instant Messaging - kABMultiDictionaryPropertyType
extern const CFStringRef kABPersonInstantMessageServiceKey; // Service ("Yahoo", "Jabber", etc.)
extern const CFStringRef kABPersonInstantMessageServiceYahoo;
extern const CFStringRef kABPersonInstantMessageServiceJabber;
extern const CFStringRef kABPersonInstantMessageServiceMSN;
extern const CFStringRef kABPersonInstantMessageServiceICQ;
extern const CFStringRef kABPersonInstantMessageServiceAIM;
// URLs
extern const ABPropertyID kABPersonURLProperty; // URL - kABMultiStringPropertyType
extern const CFStringRef kABPersonHomePageLabel; // Home Page
// Related names
extern const ABPropertyID kABPersonRelatedNamesProperty; // Names - kABMultiStringPropertyType
extern const CFStringRef kABPersonFatherLabel; // Father
extern const CFStringRef kABPersonMotherLabel; // Mother
extern const CFStringRef kABPersonParentLabel; // Parent
extern const CFStringRef kABPersonBrotherLabel; // Brother
extern const CFStringRef kABPersonSisterLabel; // Sister
extern const CFStringRef kABPersonChildLabel; // Child
extern const CFStringRef kABPersonFriendLabel; // Friend
extern const CFStringRef kABPersonSpouseLabel; // Spouse
extern const CFStringRef kABPersonPartnerLabel; // Partner
extern const CFStringRef kABPersonAssistantLabel; // Assistant
extern const CFStringRef kABPersonManagerLabel; // Manager
Many Attributes use a set of common tags to identify work, home, and other locations. These general labels are as follows:
Kabworklabel
Kabhomelabel
Kabotherlabel
Write Multiple Attribute entries:
To add a value to an existing attribute, you must first reproduce the multi-value dictionary from the record. Then, copy the abmultivalueaddvalueandlabel function and add the new value-label to the dictionary. Finally, use the function abrecordsetvalue to write dictionary entries back to the address book record, Completely replacing the entire multi-value attribute.
7. Use a dictionary
Address book records use dictionaries to represent addresses and instant messaging accounts. These dictionaries are embedded in multi-value attribute entries. To access these dictionaries, copy the values and convert them to nsdictionary *. Then you can use a set of predefined key values to access the dictionary.
8. Image Data
Some contacts may have associated images. You can use the abpersoncopyimagedata function to obtain the image data. The returned result is a cfdataref. It can be converted to nsdata * and then used to initialize a uiimage object.
if (ABPersonHasImageData(record)) { UIImage *addressVookImage = [UIImage imageWithData:(NSData*)ABPersonCopyImageData(record)]; }
9. Address Book Interface
The address book interface framework provides two key user interfaces: A "Find someone" navigation control to select contacts, and a view control to display a single contact.
1. Contact View
Abpersonviewcontroller provides a simple interface for displaying a contact to users. The contact view requires a cfrecordref.
ABPersonViewController *viewController = [[ABPersonViewController alloc]init];
You can assign the record you want to display to the displayedperson attribute:
viewController.displayedPerson=record;
Then, you can create an array containing the attributes you want to display to the user. Only the specified attributes are displayed. However, if a contact is modified, all attributes are displayed. The available property values are the same as the enumerated values mentioned above. Each object is added to the array as an nsnumber object.
NSMutableArray* properties = [[NSMutableArray alloc]init];
[properties addObject:[NSNumber numberWithInt:kABPersonFirstNameProperty ]];
[properties addObject:[NSNumber numberWithInt:kABPersonLastNameProperty ]];
[properties addObject:[NSNumber numberWithInt:kABPersonOrganizationProperty ]];
viewController.allowsEditing =YES;
10. Contact Selector
If the application needs to select a series of contacts, the abpeoplepickernavigationcontroller class is suitable for you. This navigation control displays contacts and allows users to select one of them. After the selection, you can choose to show the contact to the user, or implement your own behavior through a delegate method.
ABPeoplePickerNavigationController* peoplePicker = [[ABPeoplePickerNavigationController alloc]init];
If you want to allow users to view a single contact, you can assign a group of attributes that you want users to see. By default, all projects are displayed to the user. Available attribute values are the enumerated values described in this chapter. Each nsnumber object is added to the array:
NSMutableArray* properties = [[NSMutableArray alloc]init];
[properties addObject:[NSNumber numberWithInt:kABPersonFirstNameProperty ]];
[properties addObject:[NSNumber numberWithInt:kABPersonLastNameProperty ]];
[properties addObject:[NSNumber numberWithInt:kABPersonOrganizationProperty ]];
peoplePicker.displayedProperties = properties;
You can specify a delegate to receive notifications when the user selects a contact:
peoplePicker.peoplePickerDelegate =self;
[self.view addSubview:peoplePicker.view];
Delegate issue:
-(void) peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *) peoplePicker {
//cancel selection
}
-(BOOL) peoplePickerNavigationController: (ABPeoplePickerNavigationController *) peoplePicker shouldContinueAfterSelectingPerson: (ABRecordRef) person {
// Select a contact
}
-(BOOL) peoplePickerNavigationController: (ABPeoplePickerNavigationController *) peoplePicker shouldContinueAfterSelectingPerson: (ABRecordRef) person property: (ABPropertyID) property identifier: (ABMultiValueIdentifier) identifier {
// selected attributes
}