Steve Mclean
Steve Mclean

Reputation: 149

How to handle offline mode with CoreData and CloudKit?

I am building a simple app similar to Notes app by Apple, my app uses CoreData and CloudKit. Currently I am stuck with few problems related to network availability with CloudKit.

When network is available, everything goes well, CoreData saves the notes and CloudKit does too using CKModifyRecordsOperation. However, when network is absent, the app somehow keeps the operations sent while offline and pushes them the cloud when the application goes online. But, it only does when I create another operation and added to the queue, it does not do it automatically when the application become active (I brought the app from background to active mode and waited 5mins, nothing happened. Only when I queued another operation, then all pending operations were sent too)

My question here is, how to trigger the app to sent all pending operations without creating another operation?

Of course above is possible if the user didn't kill the app (Double home button then swipe away). How to handle such case? when few records created while offline and then app got killed.

I thought of flagging each record in CoreData that was successfully synced, then every time the app launches, go through those which were not synced and sync them.

Is this the right way? or Apple already have a better way to handle this and I still can't find it?

Upvotes: 2

Views: 1048

Answers (1)

Manuel
Manuel

Reputation: 338

You could definitely keep a boolean for each object to flag it as out of sync, then try to sync at launch or when connectivity is restored.

Otherwise, is longLivedOperationWasPersistedBlock getting called before your app goes in the background? If it's not, that would suggest your operations are not being properly persisted.

And according to the docs, when your app resumes you're supposed to fetch any long lived operations and add them to the container:

container.fetchAllLongLivedOperationIDs(completionHandler: { (operationIDs, error) in
if let error = error {
    print("Error fetching long lived operations: \(error)")
    // Handle error
    return
}
guard let identifiers = operationIDs else { return }
for operationID in identifiers {
    container.fetchLongLivedOperation(withID: operationID, completionHandler: { (operation, error) in
        if let error = error {
            print("Error fetching operation: \(operationID)\n\(error)")
            // Handle error
            return
        }
        guard let operation = operation else { return }
        // Add callback handlers to operation
        container.add(operation)
    })
}

})

Upvotes: 3

Related Questions