ABAddressbook 을 사용하여 기존사용자에 새로운 필드를 추가하자.
제목이 너무 거창한것 같아서 스크린샷으로 요약
(before) (after)
해야 할 작업 순위 요약.
1. 주소록을 불러온다.
2. 주소록에서 내가 필드에 추가할 번호로 record id(주소록 한명의 고유번호)를 얻는다.
3. 그 해당번호의 필드에 새로운 번호를 저장한다.
4. 기존의 번호들을 새로운필드에 이어 계속 저장한다.
5. 주소록 관련된 객체들 Release (이 부분은 ARC를 사용하더라도 CFRelease를 사용해야 한다.)
#import <AddressBook/AddressBook.h>
(헤더파일 추가와 Framework 추가는 잊지말자.)
+ (void)setAddressbookField:(NSString *)phoneNum withTestFieldNumber:(NSString *)testFieldNumber withRecordId:(NSNumber *)recordId{
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, [recordId intValue]);
/*
주소록에서 한명의 주소록의 내용을 불러올때 사용되는 객체 중 ABMultiValueRef 와 ABMutableMultiValueRef 이렇게 두가지로 나뉜다.
ABMultiValueRef는 쉽게 생각해서 불러오는용이라 생각하고, ABMutableMultiValueRef 는 저장하는 용도라 생각하면 편하다.
절대로 ABMutableMultiValueRef를 이용하여 저장할수 없다...(삽질해보면 마음 편함..)
우선적으로 ABMutableMultiValueRef를 이용하여 저장하면 ABMutableMultiValueRef 를 생성할떄 사용된 Property에 해당하는 내용들은 삭제된다. 그래서
ABMultiValueRef 로 불러서 기존내용의 Property 를 따로 저장 후 ABMutableMultiValueRef 로 기존내용을 저장한다.
ABMutableMultiValueRef 와 ABMultiValueRef 가 이름이 비슷하기 때문에 쓰기 편하게 saveMultiValue와 loadMultiValue 로 사용한다.
*/
ABMutableMultiValueRef saveMultiValue = ABMultiValueCreateMutable(kABPersonPhoneProperty); //저장용
ABMultiValueRef loadMultiValue = ABRecordCopyValue(person, kABPersonPhoneProperty); //불러오는용
CFIndex loadCount = ABMultiValueGetCount (loadMultiValue); //현재 kABPersonPhoneProperty 의 필드가 몇개인지 가져온다.
/* for문을 돌면서 kABPersonPhoneProperty 의 각 필드 내용을 검사한다. */
for (CFIndex i = 0;i<loadCount;i++){
/*
한개의 필드에는 Label 과 Value가 있다. Label은 필드의 이름을 가져오고(ex iPhone, 휴대전화, 집 등등)
Value는 해당 필드의 전화번호를 가져온다.
*/
// CFStringRef label = ABMultiValueCopyLabelAtIndex(loadMultiValue, i); //필드의 Label을 가져옴.
CFStringRef value = ABMultiValueCopyValueAtIndex(loadMultiValue, i); //필드의 Value를 가져옴.
/* ABMultiValueRef에 testFieldNumber 가 없을때만 저장 하기 위해 testFieldNumber와 value를 비교한다. */
if (CFStringCompare(value, (CFStringRef)testFieldNumber, 0) == kCFCompareEqualTo) {
if (value != nil){
CFRelease(value);
}
NSLog(@"저장하려는 testFieldNumber 가 이미 있음.");
break;
}
else {
if (value != nil){
CFRelease(value);
}
/* testFieldNumber 제일 먼저 저장한다. (나머지 전화번호들은 아래 saveCount를 돌면서 저장, TestField 제일 위로 올라가기 위해 이렇게 구현함.) */
ABMultiValueAddValueAndLabel(saveMultiValue, testFieldNumber, (CFStringRef)@"TestField", NULL);
break;
}
}
//기존의 kABPersonPhoneProperty 그대로 추가하는 로직
CFIndex saveCount = ABMultiValueGetCount (loadMultiValue);
for (CFIndex i = 0;i<saveCount;i++){
/* for문을 돌면서 값들을 그대로 저장한다. */
ABMultiValueIdentifier identfier = ABMultiValueGetIdentifierAtIndex(loadMultiValue, i);
CFIndex index = ABMultiValueGetIndexForIdentifier(loadMultiValue, identfier);
CFStringRef labelString = ABMultiValueCopyLabelAtIndex(loadMultiValue, index);
CFStringRef valueString = ABMultiValueCopyValueAtIndex(loadMultiValue, index);
NSLog(@"\nindex : %ld\nlabelString : %@\nvalueString : %@\n\n", index, labelString, valueString);
ABMultiValueAddValueAndLabel(saveMultiValue, valueString, labelString, &identfier);
if (labelString !=nil){
CFRelease(labelString);
}
if (valueString !=nil){
CFRelease(valueString);
}
}
/* kABPersonPhoneProperty 에 데이터 저장 */
ABRecordSetValue(person, kABPersonPhoneProperty, saveMultiValue,nil);
if (saveMultiValue != nil){
CFRelease(saveMultiValue);
}
if (loadMultiValue !=nil){
CFRelease(loadMultiValue);
}
/* record 추가 */
ABAddressBookAddRecord(addressBook, person, nil);
/* 주소록에 저장 */
ABAddressBookSave(addressBook, nil);
CFRelease(addressBook);
}
record id 가져오는 메소드...
+ (NSNumber *)getRecordId:(NSString *)userPhoneNum {
CFStringRef phoneNum = (CFStringRef)userPhoneNum;
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
/* recordId를 가져오지 못하면 -1을 리턴하기 위해 -1로 초기화. */
NSNumber *recordId = [[[NSNumber alloc]initWithInteger:-1] autorelease];
for (NSInteger i = 0; i < nPeople ; i++) {
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
recordId = [NSNumber numberWithInteger: ABRecordGetRecordID(ref)];
ABMultiValueRef loadMultiValue = (ABMultiValueRef)ABRecordCopyValue(ref, kABPersonPhoneProperty);
for (CFIndex j = 0; j < ABMultiValueGetCount(loadMultiValue); j++) {
ABMultiValueIdentifier identfier = ABMultiValueGetIdentifierAtIndex(loadMultiValue, j);
CFIndex index = ABMultiValueGetIndexForIdentifier(loadMultiValue, identfier);
CFStringRef valueString = ABMultiValueCopyValueAtIndex(loadMultiValue, index);
if (CFStringCompare(valueString, phoneNum, 0) == kCFCompareEqualTo) {
if (valueString != nil){
CFRelease(valueString);
}
if (loadMultiValue != nil){
CFRelease(loadMultiValue);
}
CFRelease(allPeople);
CFRelease(addressBook);
NSLog(@"주소록에 있음 - recordId : %@", recordId);
return recordId;
}
if (valueString != nil){
CFRelease(valueString);
}
}
if (loadMultiValue != nil){
CFRelease(loadMultiValue);
}
}
CFRelease(allPeople);
CFRelease(addressBook);
NSLog(@"주소록에 없음 - recordId : %@", recordId);
return recordId;
}
setAddressbookField 메소드에 getRecordId 메소드에서 얻은 값을 던지면 기가막히게(?) 필드에 추가되는것을 볼 수 있다.
'iOS' 카테고리의 다른 글
ios 유니코드 처리 (0) | 2012.08.22 |
---|---|
하위뷰 모두 제거 (0) | 2012.06.21 |
UITabBarController Custom (0) | 2012.04.16 |
AVPlayerLayer 사용, 비디오 썸네일 만들기 (0) | 2012.04.10 |
앱 - 앱 간 자료 전송 방법 2가지 (0) | 2012.04.03 |