Swift concurrency

How to determine where tasks and async functions run in Swift?

Published on: February 16, 2024

Swift’s current concurrency model leverages tasks to encapsulate the asynchronous work that you’d like to perform. I wrote about the different kinds of tasks we have in Swift in the past. You can take a look at that post here. In this post, I’d like to explore the rules that Swift applies when it determines where your tasks and functions run. More specifically, I’d like to explore how we can determine whether a task or function will run on the main actor or not. We’ll start this post by very briefly looking at tasks and how we can determine where...

Read more...

Understanding unstructured and detached tasks in Swift

Published on: April 13, 2023

When you just start out with learning Swift Concurrency you’ll find that there are several ways to create new tasks. One approach creates a parent / child relationship between tasks, another creates tasks that are unstructured but do inherit some context and there’s an approach that creates tasks that are completely detached from all context. In this post, I will focus on unstructured and detached tasks. If you’re interested in learning more about child tasks, I highly recommend that you read the following posts: Running tasks in parallel with Swift Concurrency’s task groups Running tasks concurrently with Swift Concurrency’s async...

Read more...

The basics of structured concurrency in Swift explained

Published on: March 17, 2023

Swift Concurrency heavily relies on a concept called Structured Concurrency to describe the relationship between parent and child tasks. It finds its basis in the fork join model which is a model that stems from the sixties. In this post, I will explain what structured concurrency means, and how it plays an important role in Swift Concurrency. Note that this post is not an introduction to using the async and await keywords in Swift. I have lots of posts on the topic of Swift Concurrency that you can find right here. These posts all help you learn specific bits and...

Read more...

Iterating over web socket messages with async / await in Swift

Published on: January 24, 2023

In iOS 13, we gained the ability to easily send and receive data using web sockets through URLSession. With async/await, we gained the ability to fetch data from servers using the await keyword and we can iterate over asynchronous sequences using async for loops. We can even read data from a URL one line at a time by calling the lines property on URL: let url = URL(string: "https://donnywals.com")! for try await line in url.lines { // use line } While this is really cool and allows us to build apps that ingest data in real time if the server...

Read more...

Understanding Swift Concurrency’s AsyncStream

Published on: January 2, 2023

In an earlier post, I wrote about different ways that you can bridge your existing asynchronous code over to Swift’s new Concurrency system that leverages async / await. The mechanisms shown there work great for code where your code produces a single result that can be modeled as a single value. However in some cases this isn’t possible because your existing code will provide multiple values over time. This is the case for things like download progress, the user’s current location, and other similar situations. Generally speaking, these kinds of patterns would be modeled as AsyncSequence objects that you can...

Read more...

Enabling Concurrency warnings in Xcode 15

Published on: September 13, 2022

If you want to make sure that your code adopts Swift concurrency as correctly as possible in Swift 5.x, it's a good idea to enable the Strict Concurrency Checking (SWIFT_STRICT_CONCURRENCY) flag in your project. To do this, select your project's target and navigate to the Build Settings tab. Make sure you select All from the list of settings that is shown (Basic is the default) and type Strict Concurrency in the searchbar to find the Strict Concurrency Checking build setting. The screenshot below shows all the relevant parts for you to see: The default value for this setting is Minimal...

Read more...

What are Sendable and @Sendable closures in Swift?

Published on: September 13, 2022

One of the goals of the Swift team with Swift’s concurrency features is to provide a model that allows developer to write safe code by default. This means that there’s a lot of time and energy invested into making sure that the Swift compiler helps developers detect, and prevent whole classes of bugs and concurrency issues altogether. One of the features that helps you prevent data races (a common concurrency issue) comes in the form of actors which I’ve written about before. While actors are great when you want to synchronize access to some mutable state, they don’t solve every...

Read more...

The difference between checked and unsafe continuations in Swift

Published on: April 24, 2022

When you’re writing a conversion layer to transform your callback based code into code that supports async/await in Swift, you’ll typically find yourself using continuations. A continuation is a closure that you can call with the result of your asynchronous work. You have the option to pass it the output of your work, an object that conforms to Error, or you can pass it a Result. In this post, I won’t go in-depth on showing you how to convert your callback based code to async/await (you can refer to this post if you’re interested in learning more). Instead, I’d like...

Read more...

Wrapping existing asynchronous code in async/await in Swift

Published on: April 24, 2022

Swift's async/await feature significantly enhances the readability of asynchronous code for iOS 13 and later versions. For new projects, it enables us to craft more expressive and easily understandable asynchronous code, which closely resembles synchronous code. However, adopting async/await may require substantial modifications in existing codebases, especially if their asynchronous API relies heavily on completion handler functions. Fortunately, Swift offers built-in mechanisms that allow us to create a lightweight wrapper around traditional asynchronous code, facilitating its transition into the async/await paradigm. In this post, I'll demonstrate how to convert callback-based asynchronous code into functions compatible with async/await, using Swift's async...

Read more...

Comparing lifecycle management for async sequences and publishers

Published on: April 12, 2022

In my previous post you learned about some different use cases where you might have to choose between an async sequence and Combine while also clearly seeing that async sequence are almost always better looking in the examples I’ve used, it’s time to take a more realistic look at how you might be using each mechanism in your apps. The details on how the lifecycle of a Combine subscription or async for-loop should be handled will vary based on how you’re using them so I’ll be providing examples for two situations: Managing your lifecycles in SwiftUI Managing your lifecycles virtually...

Read more...