Sendable and @Sendable closures explained with code examples
Article Summary
Antoine van der Lee tackles the #1 migration blocker in Swift 6: Sendable conformance. If you're seeing data race warnings pile up, this deep dive shows exactly how to fix them.
Swift's Sendable protocol is the compiler's way of preventing data races across actors, tasks, and threads. This comprehensive guide breaks down when types get implicit conformance, how to use @Sendable closures, and the migration path from Swift 5 to Swift 6's strict concurrency checking.
Key Takeaways
- Value types with Sendable properties get automatic conformance from compiler
- Use Mutex instead of @unchecked Sendable for verifiable thread safety
- Region isolation lets non-Sendable types cross boundaries when ownership transfers
- Swift 6.2's approachable concurrency reduces Sendable diagnostics significantly
- Three strictness levels (minimal, targeted, complete) ease migration gradually
Sendable conformance is where most Swift 6 migrations stall, but following the hierarchy (value types, actors, Mutex, then @unchecked as last resort) keeps your code data-race free.
About This Article
Antoine van der Lee ran into strict concurrency warnings in Stock Analyzer that he couldn't fix within the project itself. Apple's SharedWithYou framework has an SWHighlight type that doesn't conform to Sendable, which triggered multiple capture and property storage warnings.
Van der Lee used the @preconcurrency import attribute to temporarily turn off Sendable warnings from external frameworks. This let him wait for library owners to add native Sendable support without resorting to the unsafe @unchecked Sendable escape hatch.
The project kept its data-race safety guarantees for its own code while putting external dependency issues aside. Developers could focus on fixing the 17 warnings they could actually control instead of wrestling with third-party conformance gaps.