How to fetch all long-lived operations on iOS

Short summary

When I

  1. create a long-lived CKModifyRecordsOperation on my iPhone while it is in airplane mode (no internet connection)
  2. then quit the application that created the CKModifyRecordsOperation by double tapping the home button and swiping away the application
  3. disable airplane mode and connect to the internet via a wifi network (still with the application quit)

I can see (in the CloudKit dashboard) that the operation was sent to the iCloud servers and executed properly.

But when I then reopen my app and call fetchAllLongLivedOperationIDs(...) on the same CKContainer, I get (no error and) a list of 0 operations.

-> How can I retreive the operation created in (1.)?



Detailed explanation

I am trying out CloudKit in a simple CRUD application (source can be found on GitHub). The application consists of a macOS app and a iOS app. The two applications share most of the CloudKit code.


The reference docs state that the array returned from the fetchAllLongLivedOperationIDs call is:

An array containing the identifiers for all the active long-lived operations. If a long-lived operation is canceled or completed, it is no longer an active operation, and its identifier will not be included in this array. An operation is complete if the app successfully receives the completion callback.


When I add a long-lived operation like this (while not connected to the internet): (the following code can be found here in my sample application on github)

let deletion = CKModifyRecordsOperation(recordsToSave: nil, recordIDsToDelete: [someRecordID])
deletion.isLongLived = true
deletion.start()


And then quit my app, connect to the internet and reopen my app, the following fetch: (GitHub link)

cloudContainer.fetchAllLongLivedOperationIDs { operationIDs, error in
    if let error = error {print(error)}
    print(operationIDs.count)
}

returns 0 operations and no error when I try it on my iPhone.

Like I said before, I also use the exact same code for a macOS app. And surprisinly, on macOS it does return 1 operation when I do the exact same things.


OK so I thought: maybe for some reason, in iOS the operation completes (which means: the app successfully receives the completion callback, as described in the documentation) while the app is not running (because I quit it myself). So I repeat this whole sequence (described in the summary) but I manually save the operationID, and then when I reopen the app, I fetch the operation by its ID with fetchLongLivedOperation(withID: ..., completionHandler: ...) to see if the operation was really completed in the background. But no, I get back my operation and it is still marked as active (or outstanding as it is written in its debugDescription) (GitHub link).

So for some reason the operation is still active but I am not able to retreive it using fetchAllLongLivedOperationID.


Did someone else came across this issue or am I doing something wrong?


I'm using

macOS 10.12 (16A323) on a MacBook Pro 15" (late 2013)

iOS 10.0.1 on an iPhone 5

Replies

Same problem here...


Have you solved this in the meantime?

This issue still exists in iOS 13 as far as I can tell. Only way I've been able to fetch the operation is to write the operationID to disk and then use -fetchLongLivedOperationWithID:completionHandler: