johnz
johnz

Reputation: 489

Handling CloudKit errors and CKError

This seems elemental but I can't seem to find anyway that leads me in the correct direction.

In my app I have this code to access a CloudKit record:

db.performQuery(query, inZoneWithID: nil) {(results, error) -> Void in
if error != nil {
    print("performQuery error on query:\n\(error?.description)")
        }
    else {
        for rec in results! {
             // handle the record
        }
    }
 }

This works, but sometimes I get an error; for example:

<CKError 0x155cfaa0: \"Request Rate Limited\" (7/2008); Retry after 1.9 seconds>

I understand why I get the error, but I do not know how to access the CKError object which has the information I need to wait and retry the operation after - in this case - 1.9 seconds (or whatever has been shown in the message). "error" in the closure is an NSError.

How do I access the CKError record and retrieve the CkErrorCode and retryAfter properties of that so I can gracefully handle the retry?

Sorry if this seems elemental, but I sure have not found anything that explains it.

Upvotes: 1

Views: 1595

Answers (2)

DavidA
DavidA

Reputation: 3172

By converting to CKError and accessing it's members:

db.performQuery(query, inZoneWithID: nil) {(results, error) -> Void in
    guard error == nil else
    {
        let ckError = error as!CKError
        if let retryAfter = ckError.retryAfterSeconds, retryAfter>0.0
        {
            let retryAfterDate = DispatchTime.now() + ckError.retryAfterSeconds!
            // redo the query
            return
        }
        // handle other errors
        return
    }
    // handle the record
}

Upvotes: 2

beyowulf
beyowulf

Reputation: 15321

You should check the userInfo dictionary of the NSError.

    if let retryAfterValue = error.userInfo[CKErrorRetryAfterKey] as? NSTimeInterval {
        let retryAfterDate = NSDate(timeIntervalSinceNow: retryAfterValue)
        // ...
    }

Upvotes: 5

Related Questions