iosswiftios-simulatorcloudkitckoperation

CloudKit CKdatabaseOperation does not throw error in simulator depending on .qualityOfService setting


I am basically messing around with CloudKit. I have 2 questions that I would like some help/education with.

(1) When I try to run the following code in the simulator with WiFi Turned off (To simulate network unavailability), I expect it to throw network unavailable error. However, cloudKit does not throw any error and the function does not do anything either i.e. does not execute either of the print statements inside the modifyRecordZonesCompletionBlock

self.container = CKContainer.default()
self.privateDB = self.container.privateCloudDatabase
let createZoneGroup = DispatchGroup()

createZoneGroup.enter()

let createZoneOperation = CKModifyRecordZonesOperation(recordZonesToSave: [customZone], recordZoneIDsToDelete: [])

createZoneOperation.modifyRecordZonesCompletionBlock = { (saved, deleted, error) in
if let theerror = error {
// Need to handle error
    print("Create Custom zone error \(theerror)")
} else {
    print("Custom Zone created")
}
    createZoneGroup.leave()
}

createZoneOperation.qualityOfService = .background
self.privateDB.add(createZoneOperation)

However, when I change the createZoneOperation.qualityOfService to default or userInitiated, it then throws an Error (below) as which is the expected behaviour. Why is this? Is it just a simulator anomaly or is the throwing of cloud kit errors tied to the operation quality of service and why? I cannot find any info in the cloudkit API reference for this behavior.

Create Custom zone error <CKError 0x60800005a2e0: "Partial Failure" (2/1011); "Failed to modify some record zones"; partial errors: {
    Main:__defaultOwner__ = <CKError 0x610000242910: "Network Unavailable" (3/NSURLErrorDomain:-1009); "The Internet connection appears to be offline.">
}>

(2) Also, I expected it to throw a straight up Network Unavailableerror rather than a Partial Failurefailure error with the Network Unavailable error wrapped inside it. Is this the expected behaviour? Does it always throw a Partial Failure error and then has to be unwrapped to find the containing error messages?The documentation appears to be incredibly lacking any explanation, unless I failed to look in the right place.

Any help would be very much appreciated. Thank you.


Solution

  • I'try to answer both questions...

    Network

    There's no simulator error or issue, you don't receive an error connection because .background quality of service means...

    The system performs work initiated by a user sooner than background work that can be deferred until a more optimal time.

    Maybe that's the reason why you don't receive the error, it's because system is waiting for a better network condition, while you set .default or .userInitiate the system expect a "real time" response.

    Quote from the Energy Efficiency Guide for iOS Apps

    To simulate network conditions better use Network Link Conditioner tool by Apple. Here you could find more info about it.

    Partial Error

    I'm not sure about it but I think that Partial Failure is the common wrapper for all the CKxxxxxOperation error results.

    It has sense because those operations involves 1..N CKRecords and some of them could finish ok, and others could finish with error