Modern Concurrency: Getting Started

Oct 18 2022 · Swift 5.5, iOS 15, Xcode 13.4

Part 1: Asynchronous Code

03. Your First Asynchronous App

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 02. Getting Started Next episode: 04. Asynchronous Sequences

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

00:02Most of the projects in this course interact with a server. It’s included in the course materials.

01:44For the rest of this part of the course, you’ll work on this simple ticker app. In this episode, you’ll fetch a list of stock symbols from the course server.

02:15In your browser, reload the server page to check it’s still running.

03:12In LittleJohnModel, locate availableSymbols():

func availableSymbols() async throws -> [String] {
  guard let url = URL(string: "http://localhost:8080/littlejohn/symbols")
  else {
    throw "The URL could not be created."
  }
  return []
}

04:01The async keyword indicates this function contains a suspension point, which you’ll add now… just before the return statement:

let (data, response) = try await URLSession.shared.data(from: url)
🟥return []

04:48Next, you need to verify the server response and return the fetched data. Replace the dummy return line with this code:

let (data, response) = try await URLSession.shared.data(from: url)
🟩
guard (response as? HTTPURLResponse)?.statusCode == 200 else {
  throw "The server responded with an error."
}
return try JSONDecoder().decode([String].self, from: data)

05:38Before you run the app, you need to update the SwiftUI view to use your new async method.

.padding(.horizontal)
// TODO: Call model.availableSymbols()
🟩
.onAppear {
  symbols = try await model.availableSymbols() 
}
Invalid conversion from 'async' function of type '() async throws -> ()' to synchronous function type '() -> Void'
.🟩task🟥 {
  symbols = try await model.availableSymbols()
}
.task {
  do {
    symbols = try await model.availableSymbols()
  } catch  {

  }
}
.task {
  🟩guard symbols.isEmpty else { return }🟥
  do {
} catch  {
  🟩lastErrorMessage = error.localizedDescription🟥
}

08:06How about testing whether SymbolListView catches an error thrown by availableSymbols()?