Swift’s Sendable and @Sendable closures

Why you mess me up so bad?

Steven Curtis


Photo by Kelly Sikkema on Unsplash

Ah, Swift 5.7. I knew you’d have something to make me think about. The @Sendable protocol ultimately has meant that I’ve written a new network client for myself!

*So what is Sendable, @Sendable and why should we care*

Sendable types are safe to share concurrently.

Many different kinds of types are Sendable:

- Value types (because each copy is independent)

- Actor types (because they synchronise access to their mutable state)

- Immutable classes

- Internally-synchronized classes (for example with a lock)

- @Sendable function types

Sendable describes a common but not universal property of types.

The background

I had an old network library that I used to use. Suddenly it stopped working right around the time that Swift 5.7 got released. Didn’t seem to be a coincidence and it’s the fact that the dataTask function now has @Sendable it it’s signature+. Here is the commit where I fixed that!

Now, this is the article that explains @Sendable

+I know, I shouldn’t have been mocking URLSession and I’ve a much superior new version if you would like to look at that.

Back to sendable

Swift will prevent non-Sendable types from being shared.

Since Sendable is a protocol we declare conformance like any other property. If a type has Sendable properties, the enclosing type can be declared as Sendable.

Generic types can be Sendable, for example a Pair type when both of it’s properties are sendable

struct Pair<T, U> {
var first: T
var second: U

extension Pair: Sendable where T: Sendable, U: Sendable {

@Sendable function types conform to the Sendable protocol

@Sendable places restrictions on closures

- No mutable captures

- Captures must be of Sendable type