Bird
Raised Fist0
Swiftprogramming~30 mins

Cancellation handling in Swift - Mini Project: Build & Apply

Choose your learning style10 modes available
Cancellation Handling in Swift Async Tasks
📖 Scenario: Imagine you are building a simple Swift app that fetches user data from the internet. Sometimes, the user might want to cancel the fetch if it takes too long or they change their mind.
🎯 Goal: You will create a Swift async function that simulates fetching data, add a cancellation check, and then handle the cancellation properly.
📋 What You'll Learn
Create an async function called fetchUserData() that simulates a delay
Create a Task to run fetchUserData()
Add a cancellation check inside fetchUserData() using Task.isCancelled
Cancel the Task before it finishes
Print messages to show if the task completed or was cancelled
💡 Why This Matters
🌍 Real World
Handling cancellation is important in apps where users may want to stop long-running tasks like downloads or data fetching to save time and resources.
💼 Career
Understanding cancellation in async tasks is essential for Swift developers building responsive and user-friendly iOS or macOS apps.
Progress0 / 4 steps
1
Create the async function to simulate data fetching
Write an async function called fetchUserData() that waits for 5 seconds using Task.sleep and then prints "User data fetched".
Swift
Hint

Use Task.sleep(nanoseconds: 5_000_000_000) to wait 5 seconds inside the async function.

2
Create a Task to run the async function
Create a Task called userTask that runs fetchUserData() asynchronously.
Swift
Hint

Use let userTask = Task { await fetchUserData() } to start the async task.

3
Add cancellation check inside the async function
Modify fetchUserData() to check Task.isCancelled after sleeping. If cancelled, print "Fetch cancelled" and return early.
Swift
Hint

Use if Task.isCancelled { print("Fetch cancelled"); return } after the sleep.

4
Cancel the task and print the result
Call userTask.cancel() immediately after creating the task. Then wait 6 seconds using Task.sleep to allow the task to finish or cancel.
Swift
Hint

Use userTask.cancel() to cancel and then Task.sleep(nanoseconds: 6_000_000_000) to wait.

Practice

(1/5)
1. What is the main purpose of cancellation handling in Swift concurrency?
easy
A. To create new tasks continuously
B. To speed up all running tasks
C. To restart tasks automatically
D. To stop tasks that are no longer needed

Solution

  1. Step 1: Understand cancellation handling concept

    Cancellation handling is used to stop tasks that are no longer needed to save resources.
  2. Step 2: Compare options with concept

    Only To stop tasks that are no longer needed matches the purpose of stopping unnecessary tasks.
  3. Final Answer:

    To stop tasks that are no longer needed -> Option D
  4. Quick Check:

    Cancellation handling = stop unnecessary tasks [OK]
Hint: Cancellation means stopping tasks early to save resources [OK]
Common Mistakes:
  • Thinking cancellation speeds up tasks
  • Confusing cancellation with restarting tasks
  • Assuming cancellation creates new tasks
2. Which of the following is the correct way to check for cancellation inside a Swift async task?
easy
A. if Task.cancelled() { return }
B. if Task.isCancelled { return }
C. if Task.checkCancel() { return }
D. if Task.isCancel { return }

Solution

  1. Step 1: Recall correct API for cancellation check

    The correct property to check cancellation is Task.isCancelled.
  2. Step 2: Verify syntax correctness

    if Task.isCancelled { return } uses Task.isCancelled correctly; others use invalid method or property names.
  3. Final Answer:

    if Task.isCancelled { return } -> Option B
  4. Quick Check:

    Use Task.isCancelled to check cancellation [OK]
Hint: Remember: Task.isCancelled is a property, not a method [OK]
Common Mistakes:
  • Using incorrect method names like cancelled()
  • Confusing property names with similar words
  • Missing capitalization or spelling errors
3. What will be the output of the following Swift code snippet?
Task {
    for i in 1...3 {
        try Task.checkCancellation()
        print("Running step \(i)")
        if i == 2 {
            Task.current.cancel()
        }
    }
}
medium
A. Running step 1 Running step 2
B. Running step 1 Running step 2 Running step 3
C. Running step 1
D. No output due to immediate cancellation

Solution

  1. Step 1: Understand Task.checkCancellation() behavior

    Task.checkCancellation() throws if the task is cancelled, stopping further execution.
  2. Step 2: Analyze loop and cancellation timing

    Cancellation happens when i == 2, so steps 1 and 2 print, but step 3 is skipped due to cancellation.
  3. Final Answer:

    Running step 1\nRunning step 2 -> Option A
  4. Quick Check:

    Cancellation after step 2 stops step 3 [OK]
Hint: Cancellation stops loop after current iteration [OK]
Common Mistakes:
  • Assuming all steps run despite cancellation
  • Ignoring that checkCancellation throws on cancel
  • Thinking cancellation happens before step 2
4. Identify the error in this Swift async task cancellation handling code:
Task {
    if Task.isCancelled {
        print("Cancelled")
    }
    try Task.checkCancellation()
    print("Running")
}
medium
A. Task.isCancelled check is redundant before checkCancellation()
B. Missing try keyword before Task.checkCancellation()
C. No error; code handles cancellation correctly
D. Task.isCancelled should be checked after checkCancellation()

Solution

  1. Step 1: Understand difference between Task.isCancelled and checkCancellation()

    Task.checkCancellation() throws if cancelled, so it already handles cancellation detection.
  2. Step 2: Analyze redundancy of Task.isCancelled check

    Checking Task.isCancelled before checkCancellation() is redundant because checkCancellation() will throw if cancelled.
  3. Final Answer:

    Task.isCancelled check is redundant before checkCancellation() -> Option A
  4. Quick Check:

    checkCancellation() alone suffices to detect cancellation [OK]
Hint: Use checkCancellation() to handle cancellation, no need for isCancelled first [OK]
Common Mistakes:
  • Thinking isCancelled must come before checkCancellation()
  • Missing try keyword (actually present here)
  • Assuming no error when redundancy exists
5. You want to cancel a long-running Swift async task when a user taps a cancel button. Which approach correctly handles cancellation and cleans up resources?
func performTask() async {
    let task = Task {
        do {
            for i in 1...5 {
                try Task.checkCancellation()
                print("Processing \(i)")
                try await Task.sleep(nanoseconds: 1_000_000_000)
            }
        } catch {
            print("Task was cancelled")
        }
        print("Cleanup done")
    }
    // User taps cancel button
    task.cancel()
}
hard
A. Task.cancel() should be called inside the task, not outside
B. Cleanup code will not run after cancellation
C. This code correctly cancels the task and runs cleanup after cancellation
D. Task.checkCancellation() does not throw, so cancellation is ignored

Solution

  1. Step 1: Analyze cancellation handling in the task

    Task.checkCancellation() throws when cancelled, caught by catch block which prints cancellation message.
  2. Step 2: Verify cleanup code execution

    Cleanup code runs after catch block, ensuring resources are cleaned up even after cancellation.
  3. Final Answer:

    This code correctly cancels the task and runs cleanup after cancellation -> Option C
  4. Quick Check:

    Cancellation triggers catch and cleanup runs [OK]
Hint: Use try/catch with checkCancellation() to handle cancel and cleanup [OK]
Common Mistakes:
  • Assuming cleanup won't run after cancellation
  • Calling cancel() inside the task incorrectly
  • Believing checkCancellation() does not throw
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard