Class

CKReference

A reference used to create a many-to-one relationship between records in a database.

Overview

A CKReference object creates a many-to-one relationship between records in your database. Each reference object stores information about the one record that is the target of the reference. You then save the reference object in the fields of one or more records to create a link from those records to the target. Both records must be located in the same zone of the same database.

References create a stronger relationship between records than just saving the ID of a record as a string. Specifically, you can use references to create an ownership model between two records. When the reference object’s action is set to deleteSelf, the target of the reference—that is, the record stored in the reference’s recordID property—becomes the owner of the source record. Deleting the target (owner) record deletes all its source records. (The deletion of any owned records can trigger further deletions, if those records are themselves the owners of other records.) If a record contains two or more CKReference objects whose actions are set to deleteSelf, the record is deleted when any one of its referenced objects is deleted.

To save multiple records containing references between them, save the target records first or save all the records in one operation using the same CKModifyRecordsOperation object.

Interacting with Reference Objects

You use reference objects to create strong links between two records and to search for related fields. When you create new records, you create reference objects and assign them to fields of your records. The only other time you create reference objects is when you build a search predicate to search for related records.

Linking to Another Record

To link records together and create a strong relationship between them, create a new CKReference object, initialize it with the owner record, and assign that reference object to a field of the owned record. When you design the relationships among your own records, make the owner the more important of two related records. The owner record rarely depends on any records that point to it. The owner record is also the one that you typically fetch first from the database.

Figure 1 shows an example of a relationship between a to-do list record and a set of item records that represent individual items to complete. The to-do list is the primary record, or owner, in the relationship because it represents the entire to-do list, including all items on the list. As a result, each item record has a field containing a CKReference object that points to the owning to-do list record. Listing 1 shows how to create the reference object for each item record and configure it to point at the list record.

Figure 1

The relationship between owned and owner records

Listing 1

Creating a reference between a list record and an item record

itemRecord["owningList"] = CKReference(record: listRecord, action: .deleteSelf)

An ownership type of organization is useful even if one object does not explicitly own another. Ownership helps establish the relationships between records and how you search for them in the database. Ownership does not require the deletion of the owned records whenever their owner record is deleted. You can prevent such deletions by specifying the none action when you create a CKReference object.

Searching for Related Records

When you want to find records that are related to a single owner object, you create a CKReference object and use it to build your search predicate. When you use reference objects in search predicates, the search code looks only at the ID value in the reference object. It matches the ID found in records of the specified type with the ID you provided in the CKReference object.

Listing 2 shows how to use a reference object to construct a query for the records shown in Figure 1. The listID variable is a placeholder for the record ID of the list whose items you want to retrieve. The predicate tells the query object to search the owningList field of the target records and compare the reference object there with the one in the recordToMatch variable. Executing the query operation object returns the matching records asynchronously to the completion block you provide.

Listing 2

Searching for records using a reference object

// Match item records whose owningList field points to the specified list record.
let listID = listRecord.recordID
let recordToMatch = CKReference(recordID: listID, action: .deleteSelf)
let predicate = NSPredicate(format: "owningList == %@", recordToMatch)
// Create the query object.
let query = CKQuery(recordType: "Item", predicate: predicate)
let queryOp = CKQueryOperation(query: query)
queryOp.queryCompletionBlock = { (cursor, error) in
    // Process the results…
}
// Add the CKQueryOperation to a queue to execute it and process the results asynchronously.

Topics

Initializing a Reference Object

init(recordID: CKRecordID, action: CKReferenceAction)

Initializes and returns a reference object that points to the record with the specified ID.

init(record: CKRecord, action: CKReferenceAction)

Initializes and returns a reference object that points to the specified record object.

Getting the Reference Attributes

var referenceAction: CKReferenceAction

The ownership behavior for the records.

var recordID: CKRecordID

The ID of the referenced record.

Constants

enum CKReferenceAction

Constants indicating the behavior when a referenced record is deleted.

See Also

Records

class CKRecord

A dictionary of key-value pairs that you use to fetch and save your app's data.

class CKRecordZone

The definition of a custom area for organizing related records in a database.

protocol CKRecordValue

The protocol that provides strong type checking for objects that the CloudKit framework stores on the server.

Record Operations

Asynchronously fetch or modify records.