Добавление ссылочных атрибутов

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

О моделировании отношений в Вашей схеме

Можно использовать ссылочные типы атрибута для представления и непосредственных и связей «один ко многим» между объектами модели. В Вашем коде ссылочный атрибут является a CKReference объект, инкапсулирующий рекордный ID для целевой записи и добавляющийся к исходной записи. Для представления непосредственного отношения в схеме добавьте ссылочный атрибут к исходному типу записи.

../Art/to_one_relationship_2x.png

Для представления связи «один ко многим» между объектами модели более эффективно, если ссылка от дочерней записи до родительской записи — т.е. добавьте ссылочный атрибут к дочерней записи. Дочерняя запись является источником, и родительская запись является целью в этой схеме.

Например, существует связь «один ко многим» между Artist и Artwork модели и обратное непосредственное отношение от Artwork к Artist модель.

../Art/gallery_object_model_2x.png

Для представления этих отношений в схеме добавьте ссылочный атрибут к соответствию Artwork тип записи вызывают artist. Этот ссылочный атрибут будет содержать рекордный ID Artist запись.

../Art/to_many_relationship_2x.png

Точно так же представлять связь «один ко многим» от Artist к Collection в объектной модели добавьте ссылочный атрибут к Collection запись. После выборки этих записей Вы создаете надлежащие непосредственные и связи «один ко многим» между объектами модели.

Создайте ссылочные атрибуты

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

Создать ссылку от одной записи до другого

  1. Создайте или получите рекордный ID для целевой записи.

    CKRecordID *artistRecordID = [[CKRecordID alloc] initWithRecordName:@"Mei Chen"];
  2. Создайте ссылочный объект путем передачи рекордного ID цели в качестве параметра.

    CKReference *artistReference = [[CKReference alloc] initWithRecordID:artistRecordID action:CKReferenceActionNone];
  3. Добавьте ссылочный объект к исходной записи.

    CKRecord *artworkRecord;
    artworkRecord[@"artist"] = artistReference;

Сохраните исходную запись для создания типа записи, как описано в Создании Схемы базы данных путем Сохранения Записей. Если Вы хотите сохранить многократные записи, содержащие ссылки между ними, сохраните все записи в одной работе, как описано в Использовании Единственная Работа, чтобы Сохранить и Выбрать Многократные Записи. CloudKit гарантирует, что целевые записи сохраняются перед исходными записями.

Проверьте свои шаги

В Инструментальной панели CloudKit просмотрите типы записи, как описано в поле зрения Типы записи при помощи Инструментальной панели CloudKit. Ссылочный атрибут должен появиться в исходном типе записи. Например, artist атрибут в Artwork тип записи появляется как a Reference тип атрибута.

../Art/10_verify_reference_record_type_2x.png../Art/10_verify_reference_record_type_2x.png

Просмотрите записи, как описано в поле зрения Записи Используя Инструментальную панель CloudKit. Целевое рекордное имя должно появиться в исходной записи. Например, Mei Chen появляется как artist атрибут в Little Cable Car Artwork запись.

../Art/10_verify_reference_record_2x.png../Art/10_verify_reference_record_2x.png

Записи выборки со ссылочными атрибутами

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

Если возможно, пакет выбирает для разрешения отношений между объектами модели, как описано в Использовании Единственная Работа, чтобы Сохранить и Выбрать Многократные Записи.

Разрешите непосредственные отношения

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

Выбирать цель непосредственного отношения

  1. Получите ссылочный атрибут.

    CKRecord *artworkRecord;
    CKReference *referenceToArtist = artworkRecord[@"artist"];
  2. Получите целевой рекордный ID от ссылки.

    CKRecordID *artistRecordID = artistReference.recordID;
  3. Выберите целевую запись.

    [publicDatabase fetchRecordWithID:artistRecordID completionHandler:^(CKRecord *artistRecord, NSError *error) {
        if (error) {
            // Failed to fetch record
        }
        else {
            // Successfully fetched record
        }
    }];

    Добавьте свой код к fetchRecordWithID:completionHandler: параметр обработчика завершения. Например, добавьте код для создания непосредственного отношения между соответствием Artwork и Artist объекты.

Разрешите связи «один ко многим»

Для связей «один ко многим» выберите все дочерние элементы родительской записи сразу с помощью предиката. Можно выбрать все записи, имеющие родителя как его целевую запись.

Выбирать дочерние элементы связи «один ко многим»

  1. Запустите с родительского рекордного ID (CKRecordID) то, что Вы ранее выбрали и объект модели для родителя.

    Например, создайте Artist объект модели от Artist запись.

    __block Artist *artist = [[Artist alloc] initWithRecord:artistRecord];

    Использовать __block так, чтобы можно было получить доступ к родительскому объекту в обработчике завершения позже.

  2. Создайте объект предиката выбрать дочерние записи.

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@“artist = %@”, artistRecordID];

    В Вашем коде, замене artist с именем ссылочного атрибута в дочерней записи и заменой artistRecordID с родительским рекордным ID.

  3. Создайте объект запроса указание типа записи для поиска.

    CKQuery *query = [[CKQuery alloc] initWithRecordType:@“Artwork” predicate:predicate];

    В Вашем коде, замене @“Artwork” с именем дочернего типа записи.

  4. Выполните выборку.

    CKDatabase *publicDatabase = [[CKContainer containerWithIdentifier:[CKContainer defaultContainer]] publicCloudDatabase];
    [publicDatabase performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {
        if (error) {
            // Failed to fetch children of parent
        }
        else {
            // Create model objects for each child and set the one-to-many relationship from the parent to its children
        }
    }];

    Добавьте код к else оператор, создающий соответствующие отношения между Вашими объектами модели.

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

Более эффективно обработать в пакетном режиме, сохраняет и выборки многократных записей в единственную работу. Если типы записи содержат ссылочные атрибуты, это особенно важно. Можно сохранить новые входные и выходные записи в одной работе с помощью a CKModifyRecordsOperation объект. Можно создать ссылку на целевую запись, не имеющую идентификатора. Пока Вы спасаете обоих входные и выходные записи вместе, CloudKit гарантирует это в графике связанных CKRecord объекты, целевые записи сохраняются перед исходными записями. Можно также выбрать все цели ряда исходных записей в одной работе с помощью a CKFetchRecordsOperation объект.

Выбирать многократные записи в единственной работе

  1. Добавьте весь рекордный IDs для записей, которые Вы хотите выбрать к массиву.

    Например, для выборки многократных непосредственных отношений добавьте, что весь целевой рекордный IDs ссылки приписывает массиву.

  2. Создайте объект операции записи выборки путем передачи массива рекордного IDs в качестве параметра.

    CKFetchRecordsOperation *fetchRecordsOperation = [[CKFetchRecordsOperation alloc] initWithRecordIDs:fetchRecordIDs];
  3. Дополнительно, обеспечьте на рекордный обработчик завершения.

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

    fetchRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record, CKRecordID *recordID, NSError *error) {
        if (error) {
            // Retain the record IDs for failed fetches
        }
        else {
            // Create a model object and set any relationships to other models
        }
    };
  4. Установите обработчик завершения для всей работы.

    fetchRecordsOperation.fetchRecordsCompletionBlock = ^(NSDictionary *recordsByRecordID, NSError *error) {
        if (error) {
            // Failed to fetch all or some of the records
        }
        else {
            // Update all associated views
        }
    };

    При сохранении рекордного IDs в на рекордный обработчик завершения на шаге 3 можно попытаться выбрать отказавшие записи снова.

  5. Запустите работу.

    CKDatabase *database = [[CKContainer containerWithIdentifier:[CKContainer defaultContainer]] publicCloudDatabase];
    [database addOperation:fetchRecordsOperation];

Укажите владение для автоматического удаления связанных записей

Можно указать, удалена ли исходная запись ссылки, когда удалена ее целевая запись. Например, можно хотеть, чтобы дочерние элементы связи «один ко многим» были удалены, когда удален родитель. Родительской записи принадлежат дочерние записи. Если дочерним элементам будут принадлежать другие записи, то они будут также удалены, вызывая каскад удалений.

../Art/cascade_deletes_2x.png

Вы указываете удалить действие при создании ссылочного объекта. Для удаления исходной записи, когда цель будет удалена передайте целевую запись и CKReferenceActionDeleteSelf как параметр действия к initWithRecord:action: метод. В выборке Галереи укажите, что иллюстрации, принадлежащие художнику, должны быть удалены, когда удален художник.

CKReference *referenceToArtist = [[CKReference alloc] initWithRecord:artistRecord action:CKReferenceActionDeleteSelf];
artworkRecord[@"artist"] = referenceToArtist;

Также установите флажок DeleteSelf в Инструментальной панели CloudKit для каждой записи.

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

../Art/first_delete_wins_2x.png