반응형
[iOS Study] 연락처 프로그래밍 가이드 in iOS - BaseObjects |
https://developer.apple.com/library/ios/documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/BasicObjects.html#//apple_ref/doc/uid/TP40007744-CH3-SW1
-
Address Book database 를 확실히 이용하기 위해서는 4가지 요소를 잘 알아두어야 한다.
1. Address books
2. Records
3. Single-value properties
4. Multi-value properties
Address Books
-
ABAddressBookRef instance 를 ABAddressBookCreate 함수를 통해 만들어 사용하면 된다.
여러개의 ABAddressBookRef 를 만들 수 있다. 그러나 모두 같은 db 를 바라본다.
ABAddressBookRef 는 multi thread 에서 사용될 수 없다.
각 thread 는 각각의 instance 를 만들어서 사용해야 한다.
-
ABAddressBookRef 를 통해서 데이터를 읽고 쓸 수 있다.
ABAddressBookSave 를 통해 변경사항을 저장할 수 있고, 그것을 취소하려면 ABAddressBookRevert 를 호출하면 된다.
저장되지 않은 정보가 있는지 확인하려면 ABAddressBookHasUnsavedChanges 를 사용하면 된다.
ABAddressBookRef addressBook = ABAddressBookCreate();
bool wantToSaveChanges = YES;
bool didSave;
CFErrorRef error = NULL;
/* … addressBook 으로 뭔가 작업 ... */
if (ABAddressBookHasUnsavedChanges(addressBook)) {
if (wantToSaveChanges) {
didSave = ABAddressBookSave(addressBook, &error);
if (!didSave) {
/* Handle error here. */
}
} else {
ABAddressBookRevert(addressBook);
}
}
CFRelease(addressBook);
-
다른 앱에서 address book 에 무슨 작업을 했는지에 대한 notification 을 받을 수 도 있다.
ABAddressBookRegisterExternalChangeCallback 함수를 통해 ABExternalChangeCallback 을 등록하여 사용할 수 있다.
여러개의 callback 을 다른 context 에서 등록하여 사용할 수 있다.
unregister 는 ABAddressBookUnregisterExternalChangeCallback 을 사용하면 된다.
noti 를 받았을 때 할 수 있는 행동은 다음과 같다.
만약 수정사항이 없다면, revert 를 통해 최신 data 를 반영하면 된다.
수정사항이 있다면, 그리고 저장해야 하는 정보라면 save 를 수행한다. 이 save 는 merge 를 자동으로 해주지만, 확실한 merge 는 보장하지 못할 수 있으므로 merge 실패에 대한 경우도 준비는 해야 한다.
Record
-
Address Book 안의 record 란 곳에 정보가 저장되어 있다.
이 Record 는 ABRecordRef 로 매핑된다.
-
Record 는 사람과 그룹으로 구성된다.
ABRecordGetRecordType 함수는 kABPersonType 또는 kABGroupType 을 return 한다.
-
Record 는 thread-safe 하지 않기 떄문에 이 녀석을 직접 공유하지 말고, record identifier 를 공유해서 사용하는 방식으로 해야 한다.
-
Record 는 Address Book 안에 있지만, Address Book 밖에도 존재할 수 있다.
-
Record 안에는 properties 들이 collection 으로 들어 있다.
ABRecordCopyValue 와 ABRecordSetValue 가 Record 에 대한 get/set property 이다.
ABRecordRemoveValue 를 통해서 값이 제거될 수도 있다.
-
Person Record
first name, last name 은 single value property 이다.
street address, phone number 등은 multivalue property 이다.
-
Group Record
그룹은 kABGroupNameProperty 라는 한 가지 property 만 갖는다.
group 에 속한 모든 맴버를 얻으려면 ABGroupCopyArrayOfAllMembers 함수나 ABGroupCopyArrayOfAllMembersWithSortOrdering 을 사용하면 된다.
위의 함수들은 ABRecordRef 를 element 로 가진 CFArrayRef 를 return 한다.
Properties
-
2개의 타입이 있다. single-value property 와 multvalue property 이다.
Multivalue property 중에는 mutable 과 immutable 이 있다.
-
Single-value property
ABRecordRef newPersonRecord = ABPersonCreate();
CFErrorRef anError = NULL;
bool didSet; = ABRecordSetValue(newPersonRecord , kABPersonFirstNameProperty, CFSTR("Katie"), &anError);
if (!didSet) {
/* Handle error here. */
}
didSet = ABRecordSetValue(newPersonRecord , kABPersonLastNameProperty, CFSTR("Bell"), &anError);
if (!didSet) {
/* Handle error here. */
}
CFStringRef firstName, lastName;
firstName = ABRecordCopyValue(aRecord, kABPersonFirstNameProperty);
lastName = ABRecordCopyValue(aRecord, kABPersonLastNameProperty);
/* ... Do something with firstName and lastName. ... */
CFRelease(aRecord);
CFRelease(firstName);
CFRelease(lastName);
-
Multivalue Properties
Multivalue property 는 여러개의 value 로 구성되어 있다.
각각의 value 는 id 와 text label 을 갖는다.
text label 은 여러 개의 value 에 assign 될 수 있다.
multivalue 의 value 는 index 혹은 id 로 접근 가능하다.
index 와 id 간의 치환은 다음 2개의 함수로 가능하다. ABMultiValueGetIndexForIndentifier 또는 ABMultiValueGetIdentifierAtIndex
index 는 새로운 property 가 추가 삭제되면서 변동될 수 있다는 점을 알아두어야 한다.
ABMultiValueCopyLabelAtIndex, ABMultiValueCopyValueAtIndex, ABMultiValueCopyArrayOfAllValues 등을 통해 내용에 접근할 수 있다.
-
Mutable Multivalue Properties
Multivalue objct 는 immutable 이다.
ABMultiValueCreateMutableCopy 나 ABMultiValueCreateMutable 로 mutable 한 Multivalue object 를 만들 수 있다.
add value : ABMultiValueAddValueAndLabel, ABMultiValueInsertValueAndLabelAtIndex
change value : ABMultiValueReplaceValueAtIndex, ABMultiValueReplaceLabelAtIndex
remove value : ABMultiValueRemoveValueAndLabelAtIndex
ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType);
CFErrorRef anError = NULL;
ABMultiValueIdentifier multivalueIdentifier;
bool didAdd, didSet;
didAdd = ABMultiValueAddValueAndLabel(multi, @"(555) 555-1234", kABPersonPhoneMobileLabel, &multivalueIdentifier);
if (!didAdd) {/* Handle error here. */}
didAdd = ABMultiValueAddValueAndLabel(multi, @"(555) 555-2345", kABPersonPhoneMainLabel, &multivalueIdentifier);
if (!didAdd) {/* Handle error here. */}
ABRecordRef aRecord = ABPersonCreate();
didSet = ABRecordSetValue(aRecord, kABPersonPhoneProperty, multi, &anError);
if (!didSet) {/* Handle error here. */}
CFRelease(multi);
/* ... */
CFStringRef phoneNumber, phoneNumberLabel;
multi = ABRecordCopyValue(aRecord, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) {
phoneNumberLabel = ABMultiValueCopyLabelAtIndex(multi, i);
phoneNumber = ABMultiValueCopyValueAtIndex(multi, i);
/* ... Do something with phoneNumberLabel and phoneNumber. ... */
CFRelease(phoneNumberLabel);
CFRelease(phoneNumber);
}
CFRelease(aRecord);
CFRelease(multi);
-
Street Addresses
Street address 는 dictionary 로 구성되어 있다.
각각의 value 는 label-value pair로 dictionary 에 저장된다.
ABMutableMultiValueRef address = ABMultiValueCreateMutable(kABDictionaryPropertyType);
// Set up keys and values for the dictionary.
CFStringRef keys[5];
CFStringRef values[5];
keys[0] = kABPersonAddressStreetKey;
keys[1] = kABPersonAddressCityKey;
keys[2] = kABPersonAddressStateKey;
keys[3] = kABPersonAddressZIPKey;
keys[4] = kABPersonAddressCountryKey;
values[0] = CFSTR("1234 Laurel Street");
values[1] = CFSTR("Atlanta");
values[2] = CFSTR("GA");
values[3] = CFSTR("30303");
values[4] = CFSTR("USA");
CFDictionaryRef aDict = CFDictionaryCreate( kCFAllocatorDefault, (void *)keys, (void *)values, 5, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
// Add the street address to the multivalue.
ABMultiValueIdentifier identifier;
bool didAdd;
didAdd = ABMultiValueAddValueAndLabel(address, aDict, kABHomeLabel, &identifier);
if (!didAdd) {/* Handle error here. */}
CFRelease(aDict);
/* ... Do something with the multivalue, such as adding it to a person record. ...*/
CFRelease(address);
반응형
'프로그래밍 놀이터 > iOS' 카테고리의 다른 글
[iOS] __bridge 와 __bridge_transfer (0) | 2017.06.21 |
---|---|
[iOS Study] 연락처 프로그래밍 가이드 in iOS - Direct Interacting (0) | 2017.06.20 |
[iOS] CFArray 에서 CF 가 뭔가요? (0) | 2017.06.18 |
[iOS] NS_AVAILABLE_IOS 와 NS_DEPRECATED_IOS 의 의미는? (0) | 2017.06.17 |
[iOS] 연락처 선택 modal 띄우기 (0) | 2017.06.16 |
댓글