2
votes

I make calls to the iCloud database in two different ways in my app:

1. Calling a CKDatabase convenience method works perfectly in development (simulator) and production (device) environments:

let privateDatabase = CKContainer.defaultContainer().privateCloudDatabase

privateDatabase.fetchRecordWithID(recordID, completionHandler: { (record, error) -> Void in
    // handle record and errors
})

2. Adding CKOperations to the main queue works perfectly in the development environment, and works for a while when I test in the production environment - but then arbitrarily, after a few hours of intermittent testing, this call to the database just starts hanging - no errors are produced, and no completion code is executed. (The fetchRecordWithID call still works perfectly all the time.)

let op1 = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
op1.modifyRecordsCompletionBlock = { (savedRecords, deletedRecordIDs, error) -> Void in
    // handle records and errors
    }
op1.database = privateDatabase

// let op2, op3...

NSOperationQueue.mainQueue().addOperations([
    op1,
    op2,
    op3,
    ], waitUntilFinished: false)

In the Usage panel in the CloudKit dashboard, nothing is even remotely approaching a limit. What other variables am I not considering - or what other tests can I run to figure out what's going wrong?

1
try setting the op1, op2 and op3.qualityOfService = .UserInitiatedEdwin Vermeer

1 Answers

2
votes

Try setting the op1, op2 and op3.qualityOfService = .UserInitiated

That setting has been set to a 'lower' standard value in iOS 9.

The documentation states for the qualityOfService:

The relative amount of importance for granting system resources to the operation. Service levels affect the priority with which an operation object is given access to system resources such as CPU time, network resources, disk resources, and so on. Operations with a higher quality of service level are given greater priority over system resources so that they may perform their task more quickly. You use service levels to ensure that operations responding to explicit user requests are given priority over less critical work. This property reflects the minimum service level needed to execute the operation effectively. The default value of this property is NSOperationQualityOfServiceBackground and you should leave that value in place whenever possible. When changing the service level, use the minimum level that is appropriate for executing the corresponding task. For example, if the user initiates a task and is waiting for it to finish, assign the value NSOperationQualityOfServiceUserInitiated to this property. The system may give the operation a higher service level to the operation if the resources are available to do so.