프로그램 이야기/iPhoneDev

[iPhone] 주소록에서 전화번호 가져오기

Messace 2012. 11. 8. 01:57


알림) 아래의 내용은 iOS 5.x와 iOS 6에서 작성되어진 항목입니다.
        주소록에 대한 간략한 형식과 iOS6에서 변경된 부분만 다루었습니다.


아이폰의 주소록에는 이름, 이미지, 전화번호, 기념일, 주소, 기타등이 있으며 이는 구조체 형식으로 추출하여
사용할 수 있습니다.
아래 코드는 이중 전화번호와 라벨출력을 하는것이며 나머지 다른것에 관한것도 이와 같은 방법입니다.

아이폰의 주소록의 데이터를 사용하기 위해서는 우선 Frameworks를 추가해야 합니다.
AddressBook.framework를 추가 하시고 AddressBook.h 헤더파일을 import합니다.




// 주소록 프레임웍 헤더파일.
#import <AddressBook/AddressBook.h> 


- (void)viewDidLoad {    
     [super viewDidLoad];

     [self StartContacts];
}

//======== iOS 5 & iOS 6 관련을 체크하여 실행해 줍니다 =========//
// 아래 소스는 너무 간결해서 따로 주석을 넣지 않았습니다.
- (void) StartContacts {
     ABAddressBookRef ref;
     if([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)  {
          CFErrorRef error = nil;
          ref = ABAddressBookCreateWithOptions(NULL,&error);
          if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
               ABAddressBookRequestAccessWithCompletion(ref, ^(bool granted, CFErrorRef error) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                         if (granted) {
                              [self RefContacts:ref];
                              CFRelease(ref);
                         } else  {
                              NSLog(@"비활성, 오류 마음에 드시는 메시지를 써넣으세요");
                        }
                    }); 
               });
          } else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
                [self RefContacts:ref];
                CFRelease(ref);
          } else {
               NSLog(@"장치의 설정 - 개인정보 보호 - 연락처 정보를 활성화 해주세요");
          }
     } else {
          ref = ABAddressBookCreate();
          [self RefContacts:ref];
          CFRelease(ref);
     }
}


// 기존에 4.x때에 작성해 놓은 블로그 글로 좀더 고쳐야 하는데 이 귀차니즘이... ...
- (void) RefContacts:(ABAddressBookRef) addressBook {
    //===================================================//
    // 주소록의 모든 정보를 구조체에 저장을 합니다.
    //===================================================//
    //  ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    //===================================================//
    // 저장된 구조체에서 해당 자료를 추출해 옵니다.
    //===================================================//
    for (int i = 0; i < nPeople ; i++) {	
	ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
	CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
	CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
	NSNumber *recordId = [NSNumber numberWithInteger: ABRecordGetRecordID(ref)];
	
	NSLog(@"Name : %d-%@ %@", recordId, (firstName != nil) ? (NSString *)firstName : @"",
		(lastName != nil) ? (NSString *)lastName : @"");
	
	if (firstName != nil)
		CFRelease(firstName);
	if (lastName != nil)
		CFRelease(lastName);

        // 사진이미지는 여기에 넘어옵니다.
        if (ABPersonHasImageData(ref)) {
	      NSData *contactImageData = (NSData*)ABPersonCopyImageDataWithFormat(ref,
                                             kABPersonImageFormatThumbnail);               
              UIImage *image = [[UIImage alloc] initWithData:contactImageData];              
              [contactImageData release];
		// image를 저장하는 펑션은 여기에 작성하시면 됩니다.
              [image release];
	}

	//========================================================//
	// 전화번호 구조체 및 카테고리 저장/추출
	// 전화번호 구조체에는 전화번호와 집전화, 핸드폰 이런 카테고리 구분이 있으며
	// 이것은 Label로 구별합니다.
	// Label : kABHomeLabel, kABPersonPhoneIPhoneLabel 등등...
	//=======================================================//
	ABMultiValueRef phoneNums = 
	(ABMultiValueRef)ABRecordCopyValue(ref, kABPersonPhoneProperty);
	for (CFIndex j = 0; j < ABMultiValueGetCount(phoneNums); j++) {
	     CFStringRef label = ABMultiValueCopyLabelAtIndex(phoneNums, j);
             CFStringRef tempRef = (CFStringRef)ABMultiValueCopyValueAtIndex(phoneNums, j);
		
		// 전화번호의 형태라벨별로 추출. 다른 형식도 이렇게 추출이 됩니다.
		if (CFStringCompare(label, kABPersonPhoneMobileLabel, 0) == 
                        kCFCompareEqualTo) {
			if (tempRef != nil)
				NSLog(@"Mobile: %@-%d", (NSString *)tempRef,i);
                } else if (CFStringCompare(label, kABPersonPhoneIPhoneLabel, 0) == 
                        kCFCompareEqualTo) {
			if (tempRef != nil)
				NSLog(@"iPhone: %@-%d", (NSString *)tempRef,i);
		} else if (CFStringCompare(label, kABHomeLabel, 0) == 
                        kCFCompareEqualTo) {
			if (tempRef != nil)
				NSLog(@"Home:  %@-%d", (NSString *)tempRef,i);
		}
		
		CFRelease(label);
		CFRelease(tempRef);
	}
    }
    CFRelease(allPeople);
}




한동안 주소록 관련하여 데이터 구조 및 추출에 대하여 테스트하며 지냈던게 생각나네요.



※ 블로그 글에 대한 알림
   해당 소스의 내용은 다듬어지지 않은 내용이 포함되어 있을 수 있으며 보다 더 체계적인 방법이
   있을 수 있음을 알려드립니다.