Modern Concurrency: Beyond the Basics

Oct 20 2022 Swift 5.5, iOS 15, Xcode 13.4

Part 1: AsyncStream & Continuations

8. Wrapping Callback With Continuation

Episode complete

Play next episode

Next
Save for later
About this episode
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 7. Wrapping Delegate With Continuation Next episode: 9. Unit Testing Tools

At the time of recording, Xcode 14 flags a runtime error in the location delegate continuation. If this happens to you, use Xcode 13 for the rest of Part 1.

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

You can unlock the rest of this video course, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.

Refresh your browser to make sure the course server is running or restart the server in Terminal. Continue with your project from the previous episode or open the starter project for this episode.

Wrapping callback APIs with continuation

Many of Apple’s “old” asynchronous APIs use callbacks: When you call a method like URLSession dataTask, you supply a completion handler, and this handler runs when the method finishes its work.

let address: String = 
try await withCheckedThrowingContinuation { continuation in
  
}
let address: String = try await
withCheckedThrowingContinuation { continuation in
  🟩
  AddressEncoder.addressFor(location: location) { address, error in
    
  }
  🟥
}
let address: String = try await
withCheckedThrowingContinuation { continuation in
  AddressEncoder.addressFor(location: location) { address, error in
    🟩
    switch (address, error) {
    // type action on same line, except for last case
    case (nil, let error?):  // If you get an error, throw it
      continuation.resume(throwing: error)
    case (let address?, nil):  // If you get an address, return it
      continuation.resume(returning: address)
    case (nil, nil):  // If you get nothing at all, throw a generic error
      continuation.resume(throwing: "Address encoding failed")
    // copy-paste 2nd case, remember to move let out of parentheses
    case let (address?, error?):  // If you get both address and error...
      continuation.resume(returning: address)  // return the address...
      print(error)  // and print the error
    }
    🟥
  }
}
try await say("📍 \(address)")