0
0
iOS Swiftmobile~20 mins

Await keyword in iOS Swift - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Async Greeting Screen
This screen shows a button that fetches a greeting message asynchronously using the await keyword and displays it.
Target UI
-------------------------
| Async Greeting Screen |
-------------------------
|                       |
|  [Fetch Greeting]     |
|                       |
|  Greeting:            |
|                       |
|                       |
-------------------------
Add a button labeled 'Fetch Greeting'.
When tapped, it calls an async function that waits 2 seconds and returns a greeting string.
Display the greeting text below the button after fetching.
Show a loading indicator while waiting.
Starter Code
iOS Swift
import SwiftUI

struct AsyncGreetingView: View {
    @State private var greeting: String = ""
    @State private var isLoading: Bool = false

    var body: some View {
        VStack(spacing: 20) {
            Text("Async Greeting Screen")
                .font(.title)

            Button("Fetch Greeting") {
                // TODO: Call async function here
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(8)

            if isLoading {
                ProgressView()
            }

            Text("Greeting: \(greeting)")
                .font(.headline)

            Spacer()
        }
        .padding()
    }

    // TODO: Add async function to fetch greeting
}

struct AsyncGreetingView_Previews: PreviewProvider {
    static var previews: some View {
        AsyncGreetingView()
    }
}
Task 1
Task 2
Task 3
Task 4
Solution
iOS Swift
import SwiftUI

struct AsyncGreetingView: View {
    @State private var greeting: String = ""
    @State private var isLoading: Bool = false

    var body: some View {
        VStack(spacing: 20) {
            Text("Async Greeting Screen")
                .font(.title)

            Button("Fetch Greeting") {
                Task {
                    isLoading = true
                    greeting = await fetchGreeting()
                    isLoading = false
                }
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(8)

            if isLoading {
                ProgressView()
            }

            Text("Greeting: \(greeting)")
                .font(.headline)

            Spacer()
        }
        .padding()
    }

    func fetchGreeting() async -> String {
        try? await Task.sleep(nanoseconds: 2_000_000_000) // 2 seconds
        return "Hello from async!"
    }
}

struct AsyncGreetingView_Previews: PreviewProvider {
    static var previews: some View {
        AsyncGreetingView()
    }
}

We created an async function fetchGreeting() that waits 2 seconds using Task.sleep and then returns a greeting string.

The button action uses Task to run async code. Inside, it sets isLoading to true, then calls await fetchGreeting() to wait for the greeting, updates the greeting state, and finally sets isLoading to false.

This shows a loading spinner while waiting and updates the UI with the greeting once ready.

Final Result
Completed Screen
-------------------------
| Async Greeting Screen |
-------------------------
|                       |
|  [Fetch Greeting]     |
|                       |
|  Loading...           |
|                       |
|  Greeting: Hello from |
|  async!               |
-------------------------
User taps 'Fetch Greeting' button.
A spinner appears below the button indicating loading.
After 2 seconds, spinner disappears and greeting text updates to 'Hello from async!'.
Stretch Goal
Add error handling to show an alert if fetching the greeting fails.
💡 Hint
Use try? with Task.sleep and add a Bool state to show an Alert with .alert modifier.