Articles, podcasts and news about Swift development, by John Sundell.

Concurrency logo

Concurrency

Explore Swift’s built-in concurrency system, and how to use tools like async/await and actors to write concurrent code in robust and efficient ways.

Introduced in Swift 5.5, Swift’s built-in concurrency system provides a lightweight, yet highly efficient set of tools for writing concurrent code.

That all starts with async/await, a pattern that’s become increasingly popular among modern programming languages, which enables us to utilize the language itself to manage long-running, asynchronous operations that are executed in the background. But that’s just the beginning.

The resources featured in this Discover guide will give you an introduction to the various tools and language features that Swift’s concurrency system ships with. They also contain lots of practical examples and techniques that can be useful to keep in mind when starting to adopt the concurrency system within various projects.

Tasks

A Task represents a unit of asynchronous work, and gives us access to a concurrent context in which we can call async-marked APIs to perform various operations in the background. Let’s start by exploring what role that tasks play within Swift’s concurrency system, and how we can manage their execution in terms of delays and timing:

Collections and parallelization

A very common type of situation in which parallelism and concurrent code can become especially useful is when we want to perform a set of operations for each element within a collection. The following articles illustrate a few different ways to do just that when using Swift’s concurrency system:

Compatibility with other code

Although Swift’s concurrency system is, by itself, backward compatible all the way back to iOS 13, macOS Catalina, and the rest of Apple’s operating systems released in 2019 — we still very likely need to do some amount of work to make those new features compatible with our own code.

We might also need to manually make certain async-marked system APIs backward compatible as well, as it’s just the language features themselves that are automatically compatible with earlier OS versions. So let’s take a look at how to write those kinds of bridges between the concurrency system and other Swift code:

Actors

Now, let’s move on to actors, which provide a built-in way to serialize how some piece of state is accessed and mutated — which in turn can help prevent concurrent memory issues, such as data races. Let’s take a look at how actors work, how to declare new actor types, and how the MainActor also provides a way for us to automatically dispatch UI-related code on the main thread:

Async testing

Writing unit tests that verify asynchronous code can often be quite challenging — especially when such code involves networking, system services, or other logic that needs to be mocked in order for our code to become fully testable.

Thankfully, Swift’s concurrency system makes async testing much simpler, as Apple’s XCTest framework now features built-in support for async-marked test functions. Let’s take a much closer look at that, as well as how async/await could even help us make our code more testable to begin with, in these articles:

Integrating with SwiftUI and Combine

When adopting Swift Concurrency, we’ll also likely want to integrate it with other Apple frameworks — such as SwiftUI and Combine. Let’s take a look at a few quick examples of doing just that:

Podcast episodes

Want to learn more about how Swift’s concurrency system was developed, and how people are starting to use it within different context? Then have a listen to the following podcast episodes, which contain in-depth discussions about those exact topics: