Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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()
}
like image 694
Pierce Avatar asked Oct 30 '22 04:10

Pierce


1 Answers

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.

like image 151
Aaron Brager Avatar answered Nov 10 '22 11:11

Aaron Brager