How to fetch all long-lived operations on iOS

∥☆過路亽.° 提交于 2019-12-24 01:08:56

问题


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):

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

this code can be found here in my sample application on github

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 fetchAllLongLivedOperationIDs.

Is this a known bug 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

回答1:


Taking a look at your code, it does not look like you set the longLivedOperationWasPersistedBlock on the long-lived CKOperations.

According to the longLivedOperationWasPersistedBlock documentation:

If your app exits before this block is called, the long-lived operation identifier is not included in the results of the fetchAllLongLivedOperationIDs(completionHandler:) method.

If you are force-quitting the app before the long-lived operation is persisted (which you currently don't check for - I'd suggest specifying that block and logging), that could indeed cause the issue.



来源:https://stackoverflow.com/questions/40133533/how-to-fetch-all-long-lived-operations-on-ios

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!