11/29/2017 - 9:07 PM

Swift - CloudKit - RecordZones

See: https://www.whatmatrix.com/blog/a-guide-to-cloudkit-how-to-sync-user-data-across-ios-devices/

01. Creating a Custom Zone

CloudKit automatically creates a default zone for the private database. However, you can get 
more functionality if you use a custom zone, most notably, support for fetching incremental record changes.

Since this is a first example of using an operation, here are a couple of general observations:

First, all CloudKit operations have custom completion closures (and many have intermediate closures, 
depending on the operation). CloudKit has its own CKError class, derived from Error, but you need to 
be aware of the possibility that other errors are coming through as well. Finally, one of the most 
important aspects of any operation is the qualityOfService value. Due to network latency, airplane 
mode, and such, CloudKit will internally handle retries and such for operations at a qualityOfService 
of “utility” or lower. Depending on the context, you may wish to assign a higher qualityOfService and 
handle these situations yourself.

Once set up, operations are passed to the CKDatabase object, where they’ll be executed on a
background thread.

// Create a custom zone to contain our note records. We only have to do this once.
private func createZone(completion: @escaping (Error?) -> Void) {
	let recordZone = CKRecordZone(zoneID: self.zoneID!)
	let operation = CKModifyRecordZonesOperation(recordZonesToSave: [recordZone], recordZoneIDsToDelete: [])
	operation.modifyRecordZonesCompletionBlock = { _, _, error in
		guard error == nil else {
	operation.qualityOfService = .utility
	let container = CKContainer.default()
	let db = container.privateCloudDatabase

02. CloudKit record zones (CKRecordZone) provide a mechanism for relating groups of records 
within a private database. Unless a record zone is specified when a record is saved to the 
cloud it is placed in the default zone of the target database. Custom zones can be added to 
private databases and used to organize related records and perform tasks such as writing to 
multiple records simultaneously in a single transaction. Each record zone has associated with 
it a unique record zone ID (CKRecordZoneID) which must be referenced when adding new records 
to a zone.
Adding a record zone to a private database involves the creation of a CKRecordZone instance 
initialized with the name to be assigned to the zone:
let myRecordZone = CKRecordZone(zoneName: "MyRecordZone")
The zone is then saved to the database via a call to the save method of a CKDatabase instance, 
passing through the CKRecordZone instance together with a completion handler to be called upon 
completion of the operation:

// Using a utility (save0 function)
privateDatabase.save(myRecordZone, completionHandler: 
        ({returnRecord, error in
            if let err = error {
               // Zone creation failed
            } else {
                // Zone creation suceeded