iosswiftcloudkitckerror

Parsing CloudKit Error (CKError)


I'm using CloudKit and I'm checking if a specific zone was already created.

For this example, let's say that a zone isn't set, so CloudKit retrieves me a CKError.

This CKError has a property called partialErrorsByItemID which is of type [AnyHashable : Error]?

Here's the code:

fileprivate func checkIfZonesWereCreated() {
    let privateDB = CKContainer.default().privateCloudDatabase
    let op = CKFetchRecordZonesOperation(recordZoneIDs: [zoneID1, zoneID2])
    op.fetchRecordZonesCompletionBlock = { (dict, err) in
        if let err = err as? CKError, let _err = err.partialErrorsByItemID {                    
            print(_err) 
            /* prints 
            [AnyHashable(<CKRecordZoneID: 0x60800003cba0; ownerName=__defaultOwner__, zoneName=TestZone>): <CKError 0x60400005a760: "Zone Not Found" (26/2036); server message = "Zone 'TestZone' does not exist"; uuid = ...-2DF4E13F81E2; container ID = "iCloud.com.someContainer">]
            */

            // If I iterate through the dictionary
            _err.forEach({ (k, v) in
                print("key:", k) // prints: key: <CKRecordZoneID: 0x60800002d9e0; ownerName=__defaultOwner__, zoneName=TestZone>
                print("value:", v) // prints: value: <CKError 0x60400005a760: "Zone Not Found" (26/2036); server message = "Zone 'TestZone' does not exist"; uuid = ...-2DF4E13F81E2; container ID = "iCloud.com.someContainer

            })

            return
        }
        print("dict:", dict)
    }
    privateDB.add(op)
}

How do I parse this error? I need to access the zoneName ?


Solution

  • The key in _err is a CKRecordZoneID. Once you have that, use the zoneName property to get the zone name.

    I would write your code as follows:

    fileprivate func checkIfZonesWereCreated() {
        let privateDB = CKContainer.default().privateCloudDatabase
        let op = CKFetchRecordZonesOperation(recordZoneIDs: [zoneID1, zoneID2])
        op.fetchRecordZonesCompletionBlock = { (dict, err) in
            if let err = err as? CKError {
                switch err {
                case CKError.partialFailure:
                    if let _err = err.partialErrorsByItemID {
                        for key in _err.keys {
                            if let zone = key as? CKRecordZoneID {
                                let name = zone.zoneName
                                print("Missing zone: \(name)")
                            }
                        }
    
                        return
                    }
                default:
                    break
                }
            }
            print("dict:", dict)
        }
        privateDB.add(op)
    }