Pierce Pierce - 7 months ago 114
Swift Question

CloudKit Error Differentiation

I need some help to learn how to properly handle errors when fetching records via

CloudKit
. Currently I have an app that saves numerous records in the cloud, and will load them at launch. I have been referencing the records using a
CKReference
, and anytime I save the reference I use the
CKReferenceAction.DeleteSelf
option. A problem I've encountered periodically is that when a referenced record is deleted, sometimes there can be a significant amount of time before the reference deletes itself. This has caused me to occasionally come across the situation where my app has fetched a
CKReference
for a record that no longer exists. I'm able to manually find out when this happens just by inserting
print(error!)
in my error handler. What I would like to know is how I can add some code to detect this specific error i.e.
if error.localizedDescription == ??? {
.
Here is the basic code I'm using for the fetch:

let fetch = CKFetchRecordsOperation(recordIDs: recordIDs)
fetch.perRecordCompletionBlock = { (record:CKRecord?, recordID:CKRecordID?, error: NSError?) in

if error != nil {

// Error Line A (See below)
print("ERROR! : \(error!.localizedDescription)")

// Error Line B (See below)
print("ERROR: \(error!)")

}

else if let record = record {

// Record was found
}
}
if let database = self.privateDatabase {
fetch.database = database
fetch.start()
}


And then when it tries to fetch the non-existent record, here is the error message that prints out in the compiler window:

a)
ERROR! : Error fetching record <CKRecordID: 0x10025b290; dbbda7c3-adcc-4271-848f-6702160ea34f:(_defaultZone:__defaultOwner__)> from server: Record not found


b)
ERROR: <CKError 0x125e82820: "Unknown Item" (11/2003); server message = "Record not found"; uuid = (removed); container ID = "(removed)">


Above in error line B, where it says
CKError 0x125e82820:
, can I use this to create an if statement to check for this specific error type? I really could use any help finding a way to resolve this issue properly when it happens. I have set up some loading structure for my app, and when it thinks there is a record it needs to find, but can't, it screws up my loading process. I would really appreciate any help I can get, I assume it's an easy solution, but apparently not one I've been able to find. Thank you!

UPDATE -

Thanks to @AaronBrager, I was able to find the correct solution. You can verify the error code to match it to any specific error, and the domain to make sure it's a
CKError
. Here is the solution that works for me:

let fetch = CKFetchRecordsOperation(recordIDs: recordIDs)
fetch.perRecordCompletionBlock = { (record:CKRecord?, recordID:CKRecordID?, error: NSError?) in

if error != nil {

if error!.code == CKErrorCode.UnknownItem.rawValue && error!.domain == CKErrorDomain {

// This works great!

}

}

else if let record = record {

// Record was found

}
}
if let database = self.publicDatabase {
fetch.database = database
fetch.start()
}

Answer

You should be able to uniquely identify an error's cause by inspecting its domain and code variables. Same domain and code, same problem. And unlike localizedDescription, it won't change between users.

Comments