Fetching Records

After you save records to the database, you can retrieve them using different mechanisms. Fetch individual records by record ID, or query for many records using a predicate. (A predicate defines logical conditions for searching for records.) Typically, you fetch a subset of records to display to the user at launch and then subscribe to changes that interest the user.

If you use the Location field type, you can also fetch records within a geographical region, as described in Fetch Records by Location.

Fetch Records by Identifier

If you know the record IDs for the records you want to fetch, then you can fetch by individual record ID. For example, this code fragment fetches a record named 115.

CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];
CKRecordID *artworkRecordID = [[CKRecordID alloc] initWithRecordName:@"115"];
[publicDatabase fetchRecordWithID:artworkRecordID completionHandler:^(CKRecord *artworkRecord, NSError *error) {
   if (error) {
      // Error handling for failed fetch from public database
   }
   else {
      // Display the fetched record
   }
}];

Fetch and Modify Records

You can fetch, modify, and save changes you make to individual records. This code fragment fetches an Artwork record, changes its date field value, and saves it to the database.

// Fetch the record from the database
CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];
CKRecordID *artworkRecordID = [[CKRecordID alloc] initWithRecordName:@"115"];
[publicDatabase fetchRecordWithID:artworkRecordID completionHandler:^(CKRecord *artworkRecord, NSError *error) {
   if (error) {
      // Error handling for failed fetch from public database
   }
   else {
      // Modify the record and save it to the database
      NSDate *date = artworkRecord[@"date"];
      artworkRecord[@"date"] = [date dateByAddingTimeInterval:30.0 * 60.0];
      [publicDatabase saveRecord:artworkRecord completionHandler:^(CKRecord *savedRecord, NSError *saveError) {
         // Error handling for failed save to public database
      }];
   }
}];

Query for Records Using Predicates

If you have many records and store large files in iCloud, it is unlikely that you want to store all the records locally on a device. Instead you fetch a slice of the data using a query. A query combines a record type, a predicate, and a sort descriptor where the predicate contains fields that are indexed. You build a query in code using a CKQuery object.

For example, this code fragment fetches all artwork with the specified title.

CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title = %@", @"Santa Cruz Mountains"];
CKQuery *query = [[CKQuery alloc] initWithRecordType:@"Artwork" predicate:predicate];
[publicDatabase performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {
    if (error) {
        // Error handling for failed fetch from public database
    }
    else {
        // Display the fetched records
    }
}];

In the Gallery app, the artwork with the specified title is fetched.

../Art/5_fetching_by_attribute_2x.png

Recap

In this chapter you learned how to: