http://www.zaachi.com/cs/items/iphone-access-to-adressbook.html

iPhone - Access to AdressBook

Publikováno: 10.08.2011 19:52:18

Vytvoříme si jednoduchou aplikaci, která bude umožňovat přístup k telefonnímu seznamu telefnu a dokáže z něj načíst informace o vybraných kontaktech.

Aplikace bude umožňovat vybrat několik kontaktů, pro jejich vybrání se využije aktuální seznam z telefonu, a vybrané hodnoty se zobrazí v tabulce v aplikaci.

 

Přístup k telefonnímu seznamu v iPhone není nic složitého. Využijeme přímo součást frameworku Cocoa AddressBook, která nám práci s telefonním seznamem telefonu velmi usnadní.

Vytvoření aplikace

Jako první si vytvoříme novou aplikaci, můžeme ji nazvat například SimpleAdressBook (i když se ve výsledku nejedná o adresář, ale spíše jenom o ukázu přístupu k adresáři).

Aplikaci vytvoříme jako standartní View-based application :

adress book

Vytvoření interface

Interface celé aplikace si vytvoříme například v Interface Builderu, kde tohle bude otázkou několika málo minut.

Nejprve si ovšem doplníme potřebné proměnné do hlavičkového souboru aplikace (v tomto případě to bude SimpleAdressBookViewController.h )

@interface SimpleAdressBookViewController : UIViewController {
	IBOutlet UIButton	*addButton;
	IBOutlet UIView		*myView;
	IBOutlet UILabel	*countLabel;
}

-(IBAction)addContact;
@end

Vytvořili jsme si jedno tlačítko - UIButton (bude vyvolávat akci pro výběr kontaktu), jeden UILabel (bude soužit pouze jako informační hodnota) a jeden UIView, do kterého budeme hodnoty zapisovat.

K tlačítku samozřejmě vytvoříme IBAction - v tomto případě jsme ji nazvali addContact.

Design s navázanými hodnotami může vypadat například následně:

adress book

Navíc navážeme událost na tlačítko (použijeme Touch UP Inside ):

adress book

AdressBook

Abychom mohli využívat AdressBook z Cocoa, musíme si jej přidat do projektu. To uděláme jednoudše přes tlačítko Get Info v Targets projektu (proklik přes naši aplikaci):

adress book

V levém dolním rohu vidíme tlačítko + přes které si do projektu přídáme:

adress book

V případě že jsou knihovny správně přídány do projektu, můžeme je includovat, to provedeme v hlavičkovém souboru SimpleAdressBookViewController.h, který bude vypadat následovně:

#import <UIKit/UIKit.h>
//include adressbook
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>

@interface SimpleAdressBookViewController : UIViewController {
	IBOutlet UIButton	*addButton;
	IBOutlet UIView		*myView;
	IBOutlet UILabel	*countLabel;
}

-(IBAction)addContact;
@end

Implementace

Nyní je vše připraveno a můžeme se pustit do implementace.

 

Do projektu si přídáme několik konstant, které budeme v průběhu běhu potřebovat:

int lineHeight	= 20;	//line height
int lineStart	= 100;  //start line position
int columnWidth = 100;	//width first column
int count		= 0;	//actual count of items
int maxCount	= 5;	//maximum items in list

 

Připravíme si funkci, která nám bude vracet aktální pozici pro výpis řádku s hodnotou:

/**
 Get actual line position
 **/
-(int) getActPosition{
	return lineStart + (count*lineHeight);
}

Funkce vrací pozici, která se vypočítá podle aktuálního počtu řádek.

 

Dále si připravíme funkci, která upraví popisek v UILabelu a zapíše sem aktální počet vybraných kontaktů:

/**
 Update count label
 **/
-(void)updateCountLabel{
	[countLabel setText:[NSString stringWithFormat:@"%d/%d", count, maxCount]];
}

Funkci rovnou spustíme při načtení aplikace ve funkci viewDidLoad:

- (void)viewDidLoad {
	[self updateCountLabel];
}

 

Konečně si můžeme dopsat událost addContact, která se bude spouštět při kliknutí na tlačítko:

/**
 IBAction: event to select a contact from the directory
 **/
-(IBAction)addContact{
	if (count 
< maxCount) {
		ABPeoplePickerNavigationController *adressbook = [[ABPeoplePickerNavigationController alloc] init];
		// place the delegate of the adressbook to the controll
		adressbook.peoplePickerDelegate = self;

		// showing the adressbook
		[self presentModalViewController:adressbook animated:YES];
		// releasing
		[adressbook release];
	}
	else {
		//show alert message
		UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"You can't add another contact" 
	   delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[alert show];
		[alert release];
	}
}

Funkce nejprve zkontroluje, zda počet vybraných kontaktů je menší než maximální množství, pokud ne, bude nás o tom informovat v podobě UIAlertu.

Pokud je vše vpořádku, inicializuje ABPeoplePickerNavigationController a zobrazí kontakty.

 

Na tomto místě máme přepnut screen do kontaktů telefonu - nyní mohou nastat dva případy:

 

Pro ošetření tlačítka Cancel dopíšeme funkci peoplePickerNavigationControllerDidCancel, která se v tomto případě bude volat:

/**
 Event cancel
 **/
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
	//return control back to the main controller
	[self dismissModalViewControllerAnimated:YES];
}

Funkce se vrátí zpět do načí aplikace a skryje adresář kontaktů

 

Druhá možnost, kdy uživatel vybere kontakt, je konečně ta, kterou očekáváme a pro kterou si přetížíme funkci peoplePickerNavigationController, jež se bude v tomto případě volat

/**
 peoplePickerNavigationController - containt selected adress from adress book
 **/
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
}

Co nás nejvíce zajímá je vstupní proměnná person, ze které budeme zjišťovat všechny informace.

Pro naše potřeby budeme potřebovat zjistit:

Nejjednodušší je zjištění jména a příjmení, to můžeme udělat přímo:

NSString *firstName, *lastName;
firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

V případě dalších hodnot, jako je telefon a email, musíme myslet na to, že jich může být v iPhone uloženo více než jedna hodnota, z proměnné person takto dostaneme hodnotu typu ABMultiValueRef :

ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);

Dopíšeme si funkci, která nám z ABMultiValueRef vrátí pouze jednu hodnotu:

/**
 return first exists item from multivalue
 **/
- (NSString *)getItemFromMultiValue: (ABMultiValueRef)emails{
	//if count
	if ( ABMultiValueGetCount( emails ) ) {
		for ( int i=0;i < ABMultiValueGetCount(emails);i++ ) {
			//if exists value
			if ( ABMultiValueCopyValueAtIndex(emails, i) ){
				return (NSString *)ABMultiValueCopyValueAtIndex(emails, i);
			}
		}
	}
	//return nil
	return @"";
}

Nyní můžeme v peoplePickerNavigationController volat:

NSString *email, *number;
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
email = [self getItemFromMultiValue:emails];

ABMultiValueRef numbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
number = [self getItemFromMultiValue:numbers];

Pokud bude v kontaktu uložen email nebo telefonní číslo, uloží se nám do proměnné.

 

Tím máme zjištěny všechny potřebné hodnoty a můžeme se vrátit zpět z Konktatů

[self dismissModalViewControllerAnimated:YES];

 

V poslední části musíme kontakt vypsat do obrazovky, uděláme si na to funkci addColumn, která bude vytažené hodnoty vykreslovat do tří sloupců:

/**
 Add new label into view
 **/
-(void) addColumn:(int )column: (NSString *)label{
	//calculate left padding 
	int leftPadding = 10 + ((int)column * (int)columnWidth);
	//create new label
	UILabel *cLabel = [[UILabel alloc] initWithFrame:CGRectMake(leftPadding, [self getActPosition], columnWidth, lineHeight)];
	//set label text
	[cLabel setText:label];
	//set label aligment
	[cLabel setTextAlignment:UITextAlignmentLeft];
	//set label font
	cLabel.font = [UIFont fontWithName:@"Helvetica" size: 10.0];
	//actPrice.textColor = [UIColor grayColor];
	[myView addSubview:cLabel];
	[cLabel release];
}

Vstupní parametry jsou číslo sloupce (indexovány od 0) a hodnota, kterou má na daný sloupec vypsat (doplníme do funkce peoplePickerNavigationController):

[self addColumn:0 : [NSString stringWithFormat:@"%@ %@", firstName, lastName] ];
[self addColumn:1 : [NSString stringWithFormat:@"%@", email] ];
[self addColumn:2 : [NSString stringWithFormat:@"%@", number] ];

Nakonec inkrementujeme hodnotu proměnné count a voláme funkci updateCountLabel

/**
 peoplePickerNavigationController - containt selected adress from adress book
 **/
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
	//create static variables
	NSString *firstName, *lastName, *email, *number;
	//get first name from adress book
	firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
	//get last name from adress book
	lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

	//get emails from adress book
	//emails are MultiValue!!!!!!
	ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
	//get email from MultiValue of emails
	email = [self getItemFromMultiValue:emails];

	//get number - similar to emails
	ABMultiValueRef numbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
	number = [self getItemFromMultiValue:numbers];

	// remove the controller
	[self dismissModalViewControllerAnimated:YES];

	//add values into view
	[self addColumn:0 : [NSString stringWithFormat:@"%@ %@", firstName, lastName] ];
	[self addColumn:1 : [NSString stringWithFormat:@"%@", email] ];
	[self addColumn:2 : [NSString stringWithFormat:@"%@", number] ];
	//increment count
	count++;

	//update count label
	[self updateCountLabel];
    return NO;
}

Shrnutí implementace

Ještě jednou si uvedeme celou implementaci SimpleAdressBookViewController:

//
//  SimpleAdressBookViewController.m
//  SimpleAdressBook
//
//  Created by jiri Zachar on 8/10/11.
//  Copyright 2011 Jiri Zachar. All rights reserved.
//

#import "SimpleAdressBookViewController.h"

@implementation SimpleAdressBookViewController

int lineHeight	= 20;	//line height
int lineStart	= 100;  //start line position
int columnWidth = 100;	//width first column
int count		= 0;	//actual count of items
int maxCount	= 5;	//maximum items in list

/**
 Get actual line position
 **/
-(int) getActPosition{
	return lineStart + (count*lineHeight);
}

/**
 Add new label into view
 **/
-(void) addColumn:(int )column: (NSString *)label{
	//calculate left padding 
	int leftPadding = 10 + ((int)column * (int)columnWidth);
	//create new label
	UILabel *cLabel = [[UILabel alloc] initWithFrame:CGRectMake(leftPadding, [self getActPosition], columnWidth, lineHeight)];
	//set label text
	[cLabel setText:label];
	//set label aligment
	[cLabel setTextAlignment:UITextAlignmentLeft];
	//set label font
	cLabel.font = [UIFont fontWithName:@"Helvetica" size: 10.0];
	//actPrice.textColor = [UIColor grayColor];
	[myView addSubview:cLabel];
	[cLabel release];
}

/**
 IBAction: event to select a contact from the directory
 **/
-(IBAction)addContact{
	if (count 
< maxCount) {
		ABPeoplePickerNavigationController *adressbook = [[ABPeoplePickerNavigationController alloc] init];
		// place the delegate of the adressbook to the controll
		adressbook.peoplePickerDelegate = self;

		// showing the adressbook
		[self presentModalViewController:adressbook animated:YES];
		// releasing
		[adressbook release];
	}
	else {
		//show alert message
		UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"You can't add another contact" 
												   delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[alert show];
		[alert release];
	}
}

/**
 Event cancel
 **/
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
	//return control back to the main controller
	[self dismissModalViewControllerAnimated:YES];
}

/**
 return first exists item from multivalue
 **/
- (NSString *)getItemFromMultiValue: (ABMultiValueRef)emails{
	//if count
	if ( ABMultiValueGetCount( emails ) ) {
		for ( int i=0;i < ABMultiValueGetCount(emails);i++ ) {
			//if exists value
			if ( ABMultiValueCopyValueAtIndex(emails, i) ){
				return (NSString *)ABMultiValueCopyValueAtIndex(emails, i);
			}
		}
	}
	//return nil
	return @"";
}

/**
 Update count label
 **/
-(void)updateCountLabel{
	[countLabel setText:[NSString stringWithFormat:@"%d/%d", count, maxCount]];
}

/**
 peoplePickerNavigationController - containt selected adress from adress book
 **/
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
	//create static variables
	NSString *firstName, *lastName, *email, *number;
	//get first name from adress book
	firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
	//get last name from adress book
	lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

	//get emails from adress book
	//emails are MultiValue!!!!!!
	ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
	//get email from MultiValue of emails
	email = [self getItemFromMultiValue:emails];

	//get number - similar to emails
	ABMultiValueRef numbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
	number = [self getItemFromMultiValue:numbers];

	// remove the controller
	[self dismissModalViewControllerAnimated:YES];

	//add values into view
	[self addColumn:0 : [NSString stringWithFormat:@"%@ %@", firstName, lastName] ];
	[self addColumn:1 : [NSString stringWithFormat:@"%@", email] ];
	[self addColumn:2 : [NSString stringWithFormat:@"%@", number] ];
	//increment count
	count++;

	//update count label
	[self updateCountLabel];
    return NO;
}

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
}

- (void)viewDidLoad {
	[self updateCountLabel];
}

- (void)dealloc {
    [super dealloc];
}

@end

Výsledek

Výsledná aplikace tedy umožní přes tlačítko vybrat konktaty ze seznamu kontaktů a tyto kontakty zobrazit, jak bylo uvedeno na začátku:

adress book   adress book
adress book   adress book