Give your simulator superpowers

RocketSim: An Essential Developer Tool
as recommended by Apple

Swift 6: Preparing your Xcode projects for the future

Swift 6 will be the next major release of Apple’s programming language and aims to create a fantastic development experience. Many of the latest features we know today are part of the road toward this major version bump.

The Swift development team shared their focus areas for 2023 and released a detailed road to Swift 6 post earlier. Both share a vision of the future for Swift and help you prepare and migrate your project gracefully. In this article, I’ll guide you in preparing your project for Swift 6.

What to expect from Swift 6?

All the Swift 5.x releases build-up toward the release of Swift 6 and progress on the goals presented on the road to Swift 6. Those releases might look minor initially, but examples like the async/await release in Swift 5.5 prove the opposite. We’re slowly building toward the significant next version of Swift.

The initial concurrency support release improves via proposals resulting from new pitches. That hands-on experience from developers will tell the team where to improve. You can expect similar improvements for the Swift 5.8 existentials and opaque types release that followed the generics manifesto and for Swift 5.9’s new Macros support. I always look at the accepted proposals to get a sense of short-term expected improvements.

Stay updated with the latest in Concurrency

The 2nd largest newsletter in the Apple development community with 18,598 developers. Don't miss out – Join today:


What is the release date of Swift 6?

The development team never announced a specific timeline for Swift 6. Instead, the plan is for the community to witness progress on focused efforts and goals with the release of Swift 6 when those efforts culminate.

Preparing your projects for the future of Swift

You don’t have to wait for the arrival of Swift 6 to get your hands dirty on expected changes. We can be grateful for the slow progression toward this significant release, allowing us to adapt new features in phases. The most prominent examples are the release of async/await, existentials, and macros. Even though you’re not required to migrate, you should start using these new language features today to prepare your project for the future of Swift.

Adapting latest concurrency features

With the backport of async/await to older OS versions you’re no longer blocked from adopting the latest concurrency features. It’s unrealistic to migrate your whole project at once, so I recommend investigating first. At WeTransfer, we’ve created an overview of the code we want to migrate to async/await by making use of the following build settings:

The strict concurrency checking build setting prepares you for Swift 6.0.
The strict concurrency checking build setting prepares you for Swift 6.0.

Or if you’re using Swift packages:

.target(
    name: "CoreExtensions",
    dependencies: ["Logging"],
    path: "CoreExtensions/Sources",
    swiftSettings: [
        /// Xcode 14:
        SwiftSetting.unsafeFlags(["-Xfrontend", "-strict-concurrency=complete"]),

        /// Xcode 15. Remove `=targeted` to use the default `complete`.
        .enableExperimentalFeature("StrictConcurrency=targeted")
    ],
    plugins: plugins
)

You can find more details in my dedicated article for this build setting. The warnings (or errors) triggered after enabling this setting gave us insights into areas of improvement. We aim to enable this setting by default as a team, so we’re gracefully migrating our codebase. I recommend migrating code like networking layers first since they’ll likely enable you to adopt async/await higher up in more places.

An excellent way to structure the work is by opening issues for each isolated part of improvement. Our team has been migrating many features since we created so-called ‘quick-win’ tickets that could be solved in less than a few hours: ideal if you want to finish your day with a minor task.

It’s not all about async/await

It’s essential to understand it’s not only about getting rid of closures in favor of async/await. By using the concurrency framework, you’ll allow the compiler to validate your code for thread safety. The concurrency strictness warnings will indicate which types must become sendable, preventing you from creating data races and runtime exceptions.

A note on existentials

As described in my article about existential any, Swift 6 will force you to use any in front of existentials to indicate the impact on performance. I recommend reading up on existentials and deciding whether you want to start using an explicit indication of existentials today.

Conclusion

Even though Swift 6 isn’t here yet, we can already use related major improvements to Apple’s development language today. By adapting new features early on, we prepare our projects for the future of Swift.

If you like to learn more tips on Swift, check out the Swift category page. Feel free to contact me or tweet to me on Twitter if you have any additional tips or feedback.

Thanks!