Swift concurrency
Understanding Swift’s AsyncSequence
Published on: November 1, 2021The biggest features in Swift 5.5 all revolve around its new and improved concurrency features. There's actors, async/await, and more. With these features folks are wondering whether async/await will replace Combine eventually. While I overall do not think that async/await can or will replace Combine on its own, Swift 5.5 comes with some concurrency features that provide very similar functionality to Combine. If you're curious about my thoughts on Combine and async/await specifically, I still believe that what I wrote about this topic earlier is true. Async/await will be a great tool for work that have a clearly defined start...
Read more...Using Swift’s async/await to build an image loader
Published on: September 6, 2021Async/await will be the defacto way of doing asynchronous programming on iOS 15 and above. I've already written quite a bit about the new Swift Concurrency features, and there's still plenty to write about. In this post, I'm going to take a look at building an asynchronous image loader that has support for caching. SwiftUI on iOS 15 already has a component that allows us to load images from the network but it doesn't support caching (other than what’s already offered by URLSession), and it only works with a URL rather than also accepting a URLRequest. The component will be...
Read more...Building a token refresh flow with async/await and Swift Concurrency
Published on: August 16, 2021One of my favorite concurrency problems to solve is building concurrency-proof token refresh flows. Refreshing authentication tokens is something that a lot of us deal with regularly, and doing it correctly can be a pretty challenging task. Especially when you want to make sure you only issue a single token refresh request even if multiple network calls encounter the need to refresh a token. Furthermore, you want to make sure that you automatically retry a request that failed due to a token expiration after you've obtained a new (valid) authentication token. I wrote about a flow that does this before,...
Read more...Using Swift Concurrency’s task group for tasks with varying output
Published on: August 9, 2021Earlier, I published a post on Swift Concurrency's task groups. If you haven't read that post yet, and you're not familiar with task groups, I recommend that you read that post first because I won't be explaining task groups in this post. Instead, you will learn about a technique that you can use to work around a limitation of task groups. Task groups can run a number of child tasks where every child task in the task group produces the same output. This is a hard requirement of the withTaskGroup function. This means that task groups are not the right...
Read more...How to use async let in Swift?
Published on: August 9, 2021In last week's post, I demonstrated how you can use a task group in Swift to concurrently run multiple tasks that produce the same output. This is useful when you're loading a bunch of images, or in any other case where you have a potentially undefined number of tasks to run, as long as you (somehow) make sure that every task in your group produces the same output. Unfortunately, this isn't always a reasonable thing to do. For example, you might already know that you only have a very limited, predetermined, number of tasks that you want to run. These...
Read more...Swift Concurrency’s TaskGroup explained
Published on: August 5, 2021With Apple's overhaul of how concurrency will work in Swift 5.5 and newer, we need to learn a lot of things from scratch. While we might have used DispatchQueue.async or other mechanisms to kick off multiple asynchronous tasks in the past, we shouldn't use these older concurrency tools in Swift's new concurrency model. Luckily, Swift Concurrency comes with many features already which means that for a lot of our old uses cases, a new paradigm exists. In this post, you will learn what Swift Concurrency's task groups are, and how you can use them to concurrently perform a lot of...
Read more...What are Swift Concurrency’s task local values?
Published on: June 22, 2021If you've been following along with Swift Concurrency in the past few weeks, you might have come across the term "task local values". Task local values are, like the name suggests, values that are scoped to a certain task. These values are only available within the context they're scoped to, and they are really only supposed to be used in a handful of use cases. In this post, I will explain what task local are, and more importantly I will explain how and when they are useful. For a full rundown of task local values and their design I'd like...
Read more...Preventing data races with Swift’s Actors
Published on: June 14, 2021We all know that async / await was one of this year’s big announcements WWDC. It completely changes the way we interact with concurrent code. Instead of using completion handlers, we can await results in a non-blocking way. More importantly, with the new Swift Concurrency features, our Swift code is much safer and consistent than ever before. For example, the Swift team built a revised threading model that ensures your program doesn’t spawn more threads than there are CPU cores to avoid thread explosion. This is a huge difference from GCD where every call to async would spawn a new...
Read more...WWDC Notes: Protect mutable state with Swift actors
Published on: June 8, 2021Data races make concurrency hard. They occur when two threads access the same data and at least one of them is a write. It’s trivial to write a data race, but it’s really hard to debug. Data races aren’t always clear, aren’t always reproducible, and might not always manifest in the same way. Shared mutable state is needed for a data race to occur. Value types don’t suffer from data races due to the way they work; they’re copied. When you pass an array around, copies are created. This is due to array’s value semantics. Even an object that’s a...
Read more...