Стандартные блоки: работа с записями и свойствами

Существует четыре основных вида объектов, которые необходимо понять для взаимодействия полностью с базой данных Address Book: адресные книги, записи, свойства единственного значения и свойства мультизначения. В этой главе рассматриваются, как данные хранятся в этих объектах и описывают функции, используемые для взаимодействия с ними.

Для получения информации о том, как взаимодействовать непосредственно с базой данных Address Book (например, чтобы добавить или удалить записи лица), видеть Прямое Взаимодействие: Программно Доступ к Базе данных.

Адресные книги

Объекты адресных книг позволяют Вам взаимодействовать с базой данных Address Book. Для использования адресной книги объявите экземпляр ABAddressBookRef и набор это к значению возвратилось из функции ABAddressBookCreate. Можно создать многоадресные объекты книги, но они все поддерживаются той же совместно используемой базой данных.

После создания ссылки адресной книги приложение может считать данные из нее и сохранить изменения в ней. Для сохранения изменений используйте функцию ABAddressBookSave; для отказа от них используйте функцию ABAddressBookRevert. Чтобы проверить, не сохраняются ли там изменения, используйте функцию ABAddressBookHasUnsavedChanges.

Следующий листинг кода иллюстрирует общий образец кодирования для того, чтобы сделать и сохранить изменения в базе данных адресной книги:

ABAddressBookRef addressBook;
bool wantToSaveChanges = YES;
bool didSave;
CFErrorRef error = NULL;
 
addressBook = ABAddressBookCreate();
 
/* ... Work with the address book. ... */
 
if (ABAddressBookHasUnsavedChanges(addressBook)) {
    if (wantToSaveChanges) {
        didSave = ABAddressBookSave(addressBook, &error);
        if (!didSave) {/* Handle error here. */}
    } else {
        ABAddressBookRevert(addressBook);
    }
}
 
CFRelease(addressBook);

Когда другое приложение (или другой поток в том же приложении) вносит изменения в базу данных Address Book, Ваше приложение может запросить получить уведомление. В целом необходимо зарегистрироваться для уведомления, если Вы выводите на экран существующие контакты, и Вы хотите обновить UI для отражения изменений в контактах, которые могут произойти, в то время как работает приложение.

Используйте функцию ABAddressBookRegisterExternalChangeCallback зарегистрировать функцию прототипа ABExternalChangeCallback. Можно зарегистрировать многократные обратные вызовы изменения путем вызова ABAddressBookRegisterExternalChangeCallback многократно с различными обратными вызовами или контекстами. Можно также не зарегистрировать функциональное использование ABAddressBookUnregisterExternalChangeCallback.

При получении обратного вызова изменения существует две вещи, которые можно сделать: Если у Вас нет несохраненных изменений, Ваш код должен просто вернуться Ваша адресная книга для получения большинства актуальных данных. Если Вы не сохранили изменения, Вы не можете хотеть возвращаться и терять те изменения. Если это верно, необходимо сохранить, и база данных Address Book приложит все усилия для слияния изменений с внешними изменениями. Если изменения не могут быть объединены и сбои сохранения, Однако Вы должны быть подготовлены принять другие соответствующие меры.

Записи

В базе данных Address Book информация хранится в записях, представленных ABRecordRef объекты. Каждая запись представляет лицо или группу. Функция ABRecordGetRecordType возвраты kABPersonType если запись является лицом, и kABGroupType если это - группа. Разработчики, знакомые с технологией Адресной книги на Mac OS, должны отметить, что нет отдельных классов для различных типов записей; и объекты лица и объекты группы являются экземплярами того же класса.

Даже при том, что записи обычно являются частью базы данных Address Book, они могут также существовать за пределами него. Это делает их полезным способом сохранить контактную информацию, с которой работает Ваше приложение.

В записи данные хранятся как набор свойств. Свойства, доступные для группы и объектов лица, отличаются, но функции раньше получали доступ к ним, то же. Функции ABRecordCopyValue и ABRecordSetValue получите и установите свойства, соответственно. Свойства могут также быть удалены полностью, с помощью функции ABRecordRemoveValue.

Записи лица

Записи лица составлены и из единственного значения и мультиоценивают свойства. Свойства, что у лица может быть только один из, такой как имя и фамилия, сохранены как свойства единственного значения. Другие свойства, которые лицо может иметь больше, что один из, такой как адрес расположения и телефонный номер, является свойствами мультизначения. Свойства для записей лица перечислены в нескольких разделах в Константах.

Для получения дополнительной информации о функциях, связанных с прямым редактированием содержания записей лица, посмотрите Работу с Записями Лица.

Записи группы

Пользователи могут организовать свои контакты в группы по ряду причин. Например, пользователь может создать группу, содержащую коллег, вовлеченных в проект или элементы спортивной команды, на которой они играют. Ваше приложение может использовать группы, чтобы позволить пользователю выполнять действие для нескольких контактов в их адресной книге одновременно.

Записи группы имеют только одно свойство, kABGroupNameProperty, который является именем группы. Для получения всех людей в группе используйте функцию ABGroupCopyArrayOfAllMembers или ABGroupCopyArrayOfAllMembersWithSortOrdering, которые возвращают a CFArrayRef из ABRecordRef объекты.

Для получения дополнительной информации о функциях, связанных с прямым редактированием содержания записей группы, посмотрите Работу с Записями Группы.

Свойства

Существует два основных типа свойств, единственного значения и мультизначения. Свойства единственного значения содержат данные, которые могут только иметь единственное значение, такое как имя лица. Свойства мультизначения содержат данные, которые могут иметь многократные значения, такие как телефонный номер лица. Свойства мультизначения могут быть или непостоянными или неизменными.

Для списка свойств для записей лица посмотрите многие разделы в Константах. Для свойств записей группы посмотрите Свойства Группы.

Свойства единственного значения

Следующий листинг кода иллюстрирует получение и установку значения свойства единственного значения:

ABRecordRef aRecord = ABPersonCreate();
CFErrorRef anError = NULL;
bool didSet;
 
didSet = ABRecordSetValue(aRecord, kABPersonFirstNameProperty, CFSTR("Katie"), &anError);
if (!didSet) {/* Handle error here. */}
 
didSet = ABRecordSetValue(aRecord, 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);

Свойства мультизначения

Свойства мультизначения состоят из списка значений. Каждое значение имеет текстовую метку и идентификатор, связанный с ним. Может быть больше чем одно значение с той же меткой, но идентификатор всегда уникален. Существуют константы, определенные для некоторых обычно используемых текстовых меток — посмотрите Универсальные Метки Свойства.

Например, рисунок 2-1 показывает свойство телефонного номера. Здесь, у лица есть многократные телефонные номера, каждый из которых имеет текстовую метку, такой как домой или работа и идентификатор. Обратите внимание на то, что в этом примере существует два домашних телефона; у них есть та же метка, но различные идентификаторы.

  Свойства Figure 2-1 Multivalue
Multivalue Properties

Отдельные значения свойства мультизначения именуются идентификатором или индексом, в зависимости от контекста. Используйте функции ABMultiValueGetIndexForIdentifier и ABMultiValueGetIdentifierAtIndex преобразовать между идентификаторами мультизначения и индексами.

Для хранения ссылки на определенное значение в свойстве мультизначения сохраните его идентификатор. Если значения будут добавлены или удалены, индекс изменится. Идентификатор, как гарантируют, не изменится кроме через устройства.

Следующие функции позволяют Вам считать содержание отдельного значения, которое Вы указываете его индексом:

Непостоянные свойства мультизначения

Объекты мультизначения являются неизменными; для изменения того, необходимо сделать непостоянную копию с помощью функции ABMultiValueCreateMutableCopy. Можно также создать новый непостоянный объект мультизначения использование функции ABMultiValueCreateMutable.

Следующие функции позволяют Вам изменить непостоянные свойства мультизначения:

Следующий листинг кода иллюстрирует получение и установку свойства мультизначения:

ABMutableMultiValueRef multi =
        ABMultiValueCreateMutable(kABMultiStringPropertyType);
CFErrorRef anError = NULL;
ABMultiValueIdentifier multivalueIdentifier;
bool didAdd, didSet;
 
// Here, multivalueIdentifier is just for illustration purposes; it isn't
// used later in the listing.  Real-world code can use this identifier to
// reference the newly-added value.
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);

Адреса расположения

Адреса расположения представлены как мультизначение словарей. Все вышеупомянутое обсуждение мультизначений все еще применяется к адресам расположения. Каждое из значений имеет метку, такой как домой или работа (см. Универсальные Метки Свойства), и каждое значение в мультизначении является адресом расположения, сохраненным как словарь. В значении словарь содержит ключи для различных частей адреса расположения, перечисленных в Свойстве Адреса.

Следующий листинг кода показывает, как установить и вывести на экран адрес расположения:

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);