IT tutorials
 
Mobile
 

Iphone Application : Using Address Book, Email, and Maps (part 2) - Accessing the Address Book

12/9/2012 11:33:31 AM
- Windows 10 Product Activation Keys Free 2019 (All Versions)
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire

Accessing the Address Book

There are two parts to accessing the address book: displaying a view that allows the user to choose a contact (an instance of the class ABPeoplePickerNavigationController) and reading the data that corresponds to that contact. Two steps...two frameworks that we need to add. Let’s do that now.

Adding the Address Book Frameworks and Delegate

Right-click the Frameworks group in your BestFriend project and choose Add, Existing Frameworks from the contextual menu. When prompted, find and add the AddressBook.framework and AddressBookUI.framework (as shown in Figure 2).

Figure 2. Add the Address Book and Address Book UI frameworks to your project.

If the frameworks don’t show up in the Frameworks group, drag them there to keep things tidy.

We also need to import the headers for the Address Book and Address Book UI frameworks and indicate that we implement the ABPeoplePickerNavigationControllerDelegate protocol because our BestFriendViewController will be the delegate for our Address Book People Picker, and this protocol is required of its delegate.

Modify the BestFriendViewController.h file, adding these lines to after the existing #import line:

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

Next, update the @interface line, adding <ABPeoplePickerNavigationControllerDelegate> to show that we are conforming to the ABPeoplePickerNavigationControllerDelegate protocol:

@interface BestFriendViewController : UIViewController
       <ABPeoplePickerNavigationControllerDelegate> {

Displaying the Address Book

When the user presses the button to choose a buddy, we want to show the Address Book Person Picker modal view controller, which will provide the user with the familiar interface from the Contacts application.

Add the IBAction method shown in Listing 2 to the Best_FriendViewController.m file.

Listing 2.
 1: - (IBAction)newBFF:(id)sender {
 2:     ABPeoplePickerNavigationController *picker;
 3:
 4:     picker=[[ABPeoplePickerNavigationController alloc] init];
 5:     picker.peoplePickerDelegate = self;
 6:
 7:     [self presentModalViewController:picker animated:YES];
 8:
 9:    [picker release];
10: }

In line 2, we declare picker as an instance of ABPeoplePickerNavigationController—a GUI object that displays the system’s address book. Lines 4 and 5 allocate the object and set its delegate to our BestFriendViewController (self).

Line 7 displays the people picker as a modal view over top of our existing user interface.

After the view is displayed, the picker object is released in line 9.

Handling Other Address Book Interactions

For the BestFriend application, we need to know only the friend the user has selected; we don’t want the user to go on and select or edit the contact’s properties. So we will need to implement the delegate method peoplePickerNavigationContoller:peoplePicker:shouldContinueAfterSelectingPerson to return NO when it is called—this will be our “workhorse” method. We also need our delegate methods to dismiss the person picker modal view and return control of the UI back to our BestFriendViewController.

Add the two ABPersonPickerViewControllerDelegate protocol methods in Listing 3 to the Best_FriendViewController.m file. We need to include these to handle the conditions of the user cancelling without picking someone (peoplePickerNavigationControllerDidCancel) and the user drilling down further than a “person” to a specific attribute (peoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier). Because we’re going to capture the user’s selection before he or she even can drill down, the second method can just return NO—it’s never going to get called anyway.

Listing 3.
// Called after the user has pressed cancel
// The delegate is responsible for dismissing the peoplePicker
- (void)peoplePickerNavigationControllerDidCancel:
        (ABPeoplePickerNavigationController *)peoplePicker {
    [self dismissModalViewControllerAnimated:YES];
}

// Called after a value has been selected by the user.
// Return YES if you want default action to be performed.
// Return NO to do nothing (the delegate is responsible for dismissing the
peoplePicker).
- (BOOL)peoplePickerNavigationController:
      (ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier {
    //We won't get to this delegate method
    return NO;
}

					  

Choosing, Accessing, and Displaying Contact Information

If the user doesn’t cancel the selection, the peoplePickerNavigationContoller:shouldContinueAfterSelectingPerson: delegate method will be called, and with it we are passed the selected person as an ABRecordRef. An ABRecordRef is part of the Address Book framework that we imported earlier.

We can use the C functions of the Address Book framework to read the data about this person from the address book. For this example, we read four things: the person’s first name, picture, email address, and ZIP code. We will check whether the person record has a picture before attempting to read it.

Notice that we don’t access the person’s attributes as the native Cocoa objects you might expect (namely, NSString and UIImage, respectively). Instead, the name string and the photo are returned as Core Foundation C data, and we convert it using the handy ABRecordCopyValue function from the Address Book framework and the imageWithData method of UIImage.

For the email address and ZIP code, we must deal with the possibility of multiple values being returned. For these pieces of data, we’ll again use ABRecordCopyValue to grab a reference to the set of data, and the functions ABMultiValueGetCount to make sure that we actually have an email address or ZIP code stored with the contact, and ABMultiValueCopyValueAtIndex to copy the first value that we find.

Sounds complicated? It’s not the prettiest code, but it’s not difficult to understand.

Add the final delegate method peoplePickerNavigationController:shouldContinueAfterSelectingPerson to the BestFriendViewController.m file, as shown in Listing 4.

Listing 4.
 1: - (BOOL)peoplePickerNavigationController:
 2:       (ABPeoplePickerNavigationController *)peoplePicker
 3:       shouldContinueAfterSelectingPerson:(ABRecordRef)person {
 4:
 5:     // Declare variables for temporarily handling the string data
 6:     NSString *friendName;
 7:     NSString *friendEmail;
 8:     NSString *friendZip;
 9:
10:     friendName=(NSString *)
11:                 ABRecordCopyValue(person, kABPersonFirstNameProperty);
12:     name.text = friendName;
13:     [friendName release];
14:
15:
16:     ABMultiValueRef friendAddressSet;
17:     NSDictionary *friendFirstAddress;
18:     friendAddressSet = ABRecordCopyValue(person, kABPersonAddressProperty);
19:
20:     if (ABMultiValueGetCount(friendAddressSet)>0) {
21:         friendFirstAddress = (NSDictionary *)
22:                         ABMultiValueCopyValueAtIndex(friendAddressSet,0);
23:         friendZip = [friendFirstAddress objectForKey:@"ZIP"];
24:         [friendFirstAddress release];
25:     }
26:
27:     ABMultiValueRef friendEmailAddresses;
28:    friendEmailAddresses = ABRecordCopyValue(person, kABPersonEmailProperty);
29:
30:     if (ABMultiValueGetCount(friendEmailAddresses)>0) {
31:         friendEmail=(NSString *)
32:                     ABMultiValueCopyValueAtIndex(friendEmailAddresses, 0);
33:         email.text = friendEmail;
34:         [friendEmail release];
35:     }
36:
37:     if (ABPersonHasImageData(person)) {
38:         photo.image = [UIImage imageWithData:
39:                        (NSData *)ABPersonCopyImageData(person)];
40:     }
41:
42:     [self presentModalViewController:picker animated:YES];
43:     return NO;
44: }

					  

Let’s walk through the logic we’ve implemented here. First, note that when the method is called, it is passed a person variable of the type ABRecordRef—this is a reference to the person who was chosen and will be used throughout the method.

Lines 6–8 declare variables that we’ll be using to temporarily store the name, email, and ZIP code strings that we retrieve from the address book.

Lines 10–11 use the ABRecordCopyVal method to copy the kABPersonFirstNameProperty property, as a string, to the friendName variable. Lines 12–13 set the name UILabel to this string, and then friendName is released.

Accessing an address is a bit more complicated. We must first get the set of addresses (each a dictionary) stored for the person, access the first address, then access a specific field within that set. Within address book, anything with multiple values is represented by a variable of type ABMultiValueRef. We declare a variable, friendAddressSet, of this type in line 16. This will reference all addresses of the person. Next, in line 17, we declare an NSDictionary called friendFirstAddress. We will store the first address from the friendAddressSet in this dictionary, where we can easily access its different fields (such as city, state, ZIP, and so on). In Line 18, we populate friendAddressSet by again using the ABRecordCopyVal function on the kABPersonAddressProperty of person.

Lines 20–25 execute only if ABMultiValueGetCount returns a copy of greater than zero on the friendAddressSet. If it is zero, there are no addresses associated with the person, and we should move on. If there are addresses, we store the first address in friendFirstAddress by copying it from the friendAddressSet using the ABMultiValueCopyValueAtIndex method in lines 21–22. The index we use with this function is 0—which is the first address in the set. The second address would be 1, third 2, and so on.

Line 23 uses the NSDictionary method objectForKey to grab the ZIP code string. The key for the ZIP code is simply the string "ZIP". Review the address book documentation to find all the possible keys you may want to access. Finally, Line 24 releases the friendFirstAddress dictionary.

Watch Out!

In case you’re wondering, the code here is not yet complete! We don’t actually do anything with the ZIP code just yet. This ties into the map function we use later, so, for now, we just get the value and ignore it.


This entire process is implemented again in lines 27–35 to grab the person’s first email address. The only difference is that rather than email addresses being a set of dictionaries, they’re simple a set of strings. This means that once we verify that there are email addresses stored for the contact (line 30), we can just copy the first one in the set and use it immediately as a string (lines 31 and 32). Line 33 sets the email UILabel to the user’s email address.

After all of that, you must be thinking to yourself, “Ugh, it’s got to be a pain to deal with a person’s photo.” Wrong! That’s actually the easy part! Using the ABPersonHasImageData function in line 37, we verify that person has an image stored. If he or she does, we copy it out of the address book using ABPersonCopyImageData and use that data along with the UIImage method imageWithData to return an image object and set the photo image within the interface. All of this occurs in lines 38–39.

As a final step, the modal view is dismissed in line 42.

Whew! A few new functions were introduced here, but once you get the pattern down, moving data out of address book becomes almost simple.

So, what about that ZIP code? What are we going to do with it? Let’s find out now by implementing our interactive map!

 
Others
 
- Iphone Application : Using Address Book, Email, and Maps (part 1)
- Iphone Application : Extending Application Integration
- Introducing Windows Phone 8 : Phone Specifications
- Introducing Windows Phone 8 : A Different Kind of Phone
- iPhone Application Development : Working with Rich Media - Accessing and Playing the iPod Library
- Android Application Development : Initialization in MicroJobs.java (part 2)
- Android Application Development : Initialization in MicroJobs.java (part 1)
- Android Application Development : Initialization Parameters in AndroidManifest.xml
- Iphone Application : Working with Rich Media - Using the Photo Library and Camera
- Iphone Application : Creating and Playing Audio Recordings
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
programming4us programming4us
 
Popular tags
 
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS