
This video is only available to subscribers. Start a subscription today to get access to this and 472 other videos.
Fetching Paged Images
This episode is part of a series: Hello CloudKit.
1. Hello Cloud Kit - Part 1 10 min |
2. Hello Cloud Kit - Part 2 10 min |
3. CloudKit Querying 12 min |
4. CloudKit References 7 min |
5. Fetching and Saving References 15 min |
6. Working with Images 15 min |
7. Fetching Paged Images 8 min |
8. CKRecord Upload Progress 6 min |
9. Isolating CloudKit from your Controllers 16 min |
10. Extracting CKRecordWrapper 7 min |
11. CloudKit Notes Manager 11 min |
12. CloudKit Notes Manager Continued 14 min |
Episode Links
Fetching Only Certain Keys
CloudKit will fetch all keys, including large assets which makes this infeasible for our Photo record. Instead, we'll tell CloudKit to only download the thumbnail:
let predicate = NSPredicate(format: "restaurant == %@", CKReference(recordID: restaurantID, action: .deleteSelf))
let query = CKQuery(recordType: Photo.recordType, predicate: predicate)
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["thumbnail"]
We'll also tell the request to only fetch 12 records at a time. This number should be roughly the size of a single visible page of records.
operation.resultsLimit = 12
Sorting the Results
We want the newest photo to be first in the list, so we'll add a sort option to our query. To do this, we'll have to make sure that the attribute we're sorting by (creationDate
in this case) is marked as sortable in the CloudKit Dashboard.
query.sortDescriptors = [
NSSortDescriptor(key: "creationDate", ascending: false)
]
Fetching Pages Sequentially
In order to fetch the next page of records, we'll leverage CKQueryCursor
.
We'll start by making the function recursive, accepting an optional cursor parameter:
private func loadPhotos(cursor: CKQueryCursor? = nil) {
...
}
We then need to initialize the operation with a cursor if we have one, otherwise we'll set up a new one with a query:
if let c = cursor {
operation = CKQueryOperation(cursor: c)
} else {
let predicate = NSPredicate(format: "restaurant == %@", CKReference(recordID: restaurantID, action: .deleteSelf))
let query = CKQuery(recordType: Photo.recordType, predicate: predicate)
query.sortDescriptors = [
NSSortDescriptor(key: "creationDate", ascending: false)
]
operation = CKQueryOperation(query: query)
}
When the operation is complete, we simply need to request the next page:
operation.queryCompletionBlock = { cursor, error in
if let e = error {
print("Error fetching photos: \(e)")
} else if let c = cursor {
self.loadPhotos(cursor: c)
print("Fetch more results...")
} else {
print("Done!")
DispatchQueue.main.async {
self.spinner.stopAnimating()
}
}
}