Well, this is embarrassing. You might have expected to find my homepage here. In fact I am currently too busy studying, writing iOS apps or working on other projectserver.org projects to create my own homepage. You may return whenever you like to check if that has changed somehow. Up to then, everything you find here is just a sophisticated twitter newsfeed. Enjoy.
—Sacha Guitry
—Elaine Rich
OBJECTIVES
This quick tutorial will show you the basic usage of the AddressBook API of iOS and give you an example how to
OUT OF SCOPE
In this article I will not show how to modify data or present it with the built-in view controllers. The first thing is too much for a quick start and the second thing is very good documented in the official Apple docs.
PRELIMINARIES
Before you can start accessing your address book you need to add two frameworks to your project: AddressBook and AddressBookUI. Also, do not forget to insert some test-contacts into the contacts app of the simulator as you might not want to test address book operations directly on your real address book.
GETTING STARTED
The first thing you need is the reference to your address book. There is a nice function in the API that does that work for you.
ABAddressBookRef addressBook = ABAddressBookCreate();
Now that was an easy start, wasn’t it? Next thing you need is to query the address book reference for some data. As I just want to give a simple example here I am querying for a list of all contacts.
NSArray *people = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
As you might have guessed, this function copies all of the contact information of all contacts from the address book into an array which might then be type-casted into a NSArray.
But what exactly is now pulled from the address book and stored inside the NSArray? The answer: ABRecordRef objects. These objects are generic wrappers around all kinds of entries in the address book, hence ‘record’.
By now, it is already possible to determine the number of contacts in the address book as each of the ABRecordRef objects represents one contact. To check whether there have been pulled some contacts at all, one could simply use something like
if ((people != nil) && [people count]) {
/* do something */
}
The next step would be to select a single record from the NSArray which I will do with a simple for loop to iterate over all records.
for (int i=0 ; i < [people count];i++) {
ABRecordRef ref = (ABRecordRef)[people objectAtIndex:i];
}
Up to now nothing really magical has happened and this is not going to change very much. However, the next part is the part which cost me an hour or so to figure out because there is a small lack of information concerning E-Mail addresses in the documentation.
Before we continue, I have to explain what ABSingleValueRefs and ABMultiValueRefs are. In the AddressBook API, there is a difference between properties which can only contain a single value (e.g. ‘Last Name’) and properties which contain more than one value (e.g. ‘Addresses’). Single value properties are directly accessed via their key (e.g. ‘kABPersonFirstNameProperty'):
CFStringRef first = ABRecordCopyValue(someRecord, kABPersonFirstNameProperty); CFStringRef last = ABRecordCopyValue(someRecord, kABPersonLastNameProperty);
Multi value properties are accessed by a key as well but as they return more than one value they have to be temporary stored inside another NSArray:
ABMultiValueRef emails = ABRecordCopyValue(someRecord, kABPersonEmailProperty); NSArray *mailAdresses = (NSArray *)ABMultiValueCopyArrayOfAllValues(emails);
Afterwards, each value can be extracted in some kind of a loop, for example another for loop:
for (int j=0 ; j<[mailAdresses count] ; j++) {
NSString *emailAddress = (NSString *)[mailAdresses objectAtIndex:j];
}
For more information on which keys are available and to which of the two categories they belong, please refer to the official documentation.
EXAMPLE CODE
This is the complete code of the example with some NSLog() output:
// Fetch the address book
ABAddressBookRef addressBook = ABAddressBookCreate();
// get all people from the addressbook
NSArray *people = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
if ((people != nil) && [people count]) {
NSLog(@"%d contacts have been extracted from the address book", [people count]);
for (int i=0;i < [people count];i++) {
ABRecordRef ref = (ABRecordRef)[people objectAtIndex:i];
ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);
NSArray *mailAdresses = (NSArray *)ABMultiValueCopyArrayOfAllValues(emails);
NSLog(@"contact %d has %d E-Mail addresses",i,[mailAdresses count]);
for (int j=0;j < [mailAdresses count];j++) {
NSString *emailAddress = (NSString *)[mailAdresses objectAtIndex:j];
NSLog(@"address %d: %@", j, emailAddress);
}
}
} else {
NSLog(@"No contacts have been extracted from the address book");
}
[people release];
CFRelease(addressBook);
NIGHTNIGHT by DEDDY