Is CKDatabase.save(_:completionHandler) really run synchronously?

CKDatabase save(_:completionHandler:) has a box that says the following below. Yet when I run the method, the completionHandler runs after the print statement after the call to the save method. I noticed the declaration of the method to be run synchronously has an escaping completionHandler. If the method is run synchronously, doesn't using an escaping completionHandler defeat the purpose of executing the method synchronously, or is the documentation wrong and the method is actually run asynchronously both ways?

Concurrency Note

You can call this method from synchronous code using a completion handler, as shown on this page, or you can call it as an asynchronous method that has the following declaration:

func save(_ record: CKRecord) async throws -> CKRecord

For information about concurrency and asynchronous code in Swift, see Calling Objective-C APIs Asynchronously.

Here is my essential code with the nonessentials taken out:

print("*** 1 before self.privateCloudKitDatabase.save(record)")

self.privateCloudKitDatabase.save(record) {
   
  recordReturned, errorReturned in
   
  print("*** 2 closure self.privateCloudKitDatabase.save(record)")
   
}

print("*** 3 after self.privateCloudKitDatabase.save(record)")

Here's the debug window:

*** 1 before self.privateCloudKitDatabase.save(record)

*** 3 after self.privateCloudKitDatabase.save(record)

. . . (other print statements)

*** 2 closure self.privateCloudKitDatabase.save(record)

That Concurrency Note assumes you’re using Swift concurrency, that is, you’re calling this routine from a Swift function marked as async and are using the await keep to wait for the result. The code snippet you posted is not using Swift concurrency and hence the behaviour you’re seeing is expected.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Is CKDatabase.save(_:completionHandler) really run synchronously?
 
 
Q