A complete, hands-on journey through Swift Concurrency for iOS engineers — starting from the basics of async/await
and building up to advanced concurrency patterns, real-world architecture, and performance best practices.
This open-source project is built with SwiftUI and Xcode Previews to make every concept visual and interactive.
Think of it as your free, code-first alternative to expensive courses with practical examples and best practices from real production apps.
- ✅
async/await
fundamentals - ✅ Structured concurrency with
Task
&TaskGroup
- ✅ Background work with
Task.detached
- ✅ Data streaming with
AsyncSequence
&AsyncStream
- ✅ Protecting state with
actor
&nonisolated
- ✅ Cancellation & cooperative tasks
- ✅ Mixing async code with Combine
- ✅ Performance tuning & avoiding pitfalls
This repo is perfect for:
- iOS engineers new to Swift Concurrency
- Developers migrating from completion handlers or Combine
- Senior engineers mentoring teams on async patterns
- Anyone preparing for technical interviews or code challenges
SwiftConcurrencyTutorial/
├─ 01-Beginner/
│ ├─ 1.1-WhatIsSwiftConcurrency.md
│ ├─ 1.2-AsyncAwaitBasics/
│ │ ├─ 1.2-AsyncAwaitBasics.md
│ │ ├─ AsyncAwaitBasics.swift
│ │ ├─ AsyncAwaitDemoViewModel.swift
│ │ ├─ AsyncAwaitDemoView.swift
│ │ └─ Tests/
│ ├─ 1.3-AsyncLet/
│ │ ├─ 1.3-AsyncLet.md
│ │ ├─ AsyncLetDemo.swift
│ │ ├─ AsyncLetDemoViewModel.swift
│ │ ├─ AsyncLetDemoView.swift
│ │ └─ Tests/
│
├─ 02-Intermediate/
│ ├─ 2.1-Task/
│ │ ├─ 2.1-Task.md
│ │ ├─ TaskDemo.swift
│ │ ├─ TaskDemoViewModel.swift
│ │ ├─ TaskDemoView.swift
│ │ └─ Tests/
│ ├─ 2.2-TaskGroup/
│ │ ├─ 2.2-TaskGroup.md
│ │ ├─ TaskGroupDemo.swift
│ │ ├─ TaskGroupDemoViewModel.swift
│ │ ├─ TaskGroupDemoView.swift
│ │ └─ Tests/
│ ├─ 2.3-DetachedTasks/
│ │ ├─ 2.3-DetachedTasks.md
│ │ ├─ DetachedTasksDemo.swift
│ │ ├─ DetachedTasksDemoViewModel.swift
│ │ ├─ DetachedTasksDemoView.swift
│ │ └─ Tests/
│ ├─ 2.4-Cancellation/
│ │ ├─ 2.4-Cancellation.md
│ │ ├─ CancellationDemo.swift
│ │ ├─ CancellationDemoViewModel.swift
│ │ ├─ CancellationDemoView.swift
│ │ └─ Tests/
│
├─ 03-Advanced/
│ ├─ 3.1-Actors/
│ │ ├─ 3.1-Actors.md
│ │ ├─ ActorsDemo.swift
│ │ ├─ ActorsDemoViewModel.swift
│ │ ├─ ActorsDemoView.swift
│ │ └─ Tests/
│ ├─ 3.2-AsyncSequences/
│ │ ├─ 3.2-AsyncSequences.md
│ │ ├─ AsyncSequencesDemo.swift
│ │ ├─ AsyncSequencesDemoViewModel.swift
│ │ ├─ AsyncSequencesDemoView.swift
│ │ └─ Tests/
│ ├─ 3.3-MixingWithCombine/
│ │ ├─ 3.3-MixingWithCombine.md
│ │ ├─ MixingWithCombineDemo.swift
│ │ ├─ MixingWithCombineDemoViewModel.swift
│ │ ├─ MixingWithCombineDemoView.swift
│ │ └─ Tests/
│ ├─ 3.4-PerformanceAndPitfalls/
│ │ ├─ 3.4-PerformanceAndPitfalls.md
│ │ ├─ PerformanceDemo.swift
│ │ ├─ PerformanceDemoViewModel.swift
│ │ ├─ PerformanceDemoView.swift
│ │ └─ Tests/
│
└─ Shared/
├─ MockData.swift
└─ Utilities.swift
-
What is Swift Concurrency?
- The problem it solves
- Differences from GCD & completion handlers
-
async
andawait
- Suspending functions
- Sequential async calls
- Demo: Simple network call (no cancellation yet)
-
async let
- Structured parallelism in a single scope
- Demo: Compare sequential vs parallel timing
-
Task
- Running async work in a new context
- Main actor vs background threads
- Demo: Main vs detached task execution
-
TaskGroup
- Running multiple async tasks in parallel
- Collecting and combining results
- Demo: Parallel image fetch
-
Detached Tasks
- When to use (and when not to)
- Demo: Detached background logger example
-
Cancellation
- Cooperative cancellation
- Checking for
Task.isCancelled
andTask.checkCancellation()
- Demo: Evolved network call with user and lifecycle cancellation
-
Actors
- Protecting mutable state with isolation
- Using
nonisolated
functions - Demo: Counter actor vs race condition
-
Async Sequences
AsyncSequence
&AsyncStream
- Consuming with
for await
- Demo: Timer ticks, streaming API simulation
-
Mixing with Combine
- Bridging async code with publishers
- Demo: Async sequence → Combine publisher chart
-
Performance & Pitfalls
- Avoiding priority inversions
- Understanding structured concurrency costs
- Demo: Compare naive parallel load vs tuned with priority management
- Clone the repo
- Open
SwiftConcurrencyTutorial.xcodeproj
in Xcode 15+ - Navigate to any example file in the
01-Basics
,02-Intermediate
, or03-Advanced
folder - Open the SwiftUI Preview to see the concept in action
Some examples include basic XCTest
cases to demonstrate testing async code.
Run them with: ⌘ + U
Or from terminal:
swift test
MIT
Built with ❤️ by Haider Ashfaq
Follow my Medium for cool iOS deep-dives and much more!