Will Swift Concurrency deploy back to older OSs?

Backwards compatibility isn’t just a “retardation manoeuvre”; it is critical to ensuring that Swift developers can actually use the feature, which in turn means that the core team can get feedback about how well it suits its intended purpose or whether anything needs adjusting (e.g. I expect actor reentrancy to be a big topic. How well will developers adjust? We’ll have to see).

Engineering isn’t a profession where you dream up a grand plan, entirely perfect at conception, and then just go away and build it. You constantly have to measure and adjust to realities that might only emerge as you build.


Java and .Net are not system frameworks. You can get any version of Swift on Linux too, as it isn't a system framework here either.


Fair enough, you are right in the sense that there is a tradeoff to be made, but it is enough that "enough" Swift developers can use it to provide feedback too, so exactly where to draw the line is always a fine art. I just wanted to point out that back porting features isn't for free and that you will inevitably lose momentum to some degree while doing it - and that we should respect the tradeoff that needs to be made.

I am well aware that engineering isn't a profession where you dream up a grand plan which is perfect at conception and build it, thanks - the important thing is just to get enough valid feedback and draw the line somewhere. I don't think anyone would argue for back porting everything 5 releases back. Especially since there are statistics - if 85%+ of all devices already run the latest iOS release (14), it seems likely that the same adoption rate will happen for the next release.

(I too believe that the actor reentrancy will be very interesting to follow - it seems likely to cause some trouble for many FWIW)

Not having all the details on the effort involved makes it impossible to second-guess such choices, but given that there are still a lot of fundamentally big things still missing (like e.g. memory ownership), I hope the pendulum will be swinging more towards forward thrust at this point - definitely understand others may have different views of course.


First of all, I want to thank the team for such a great concurrency model!

It is also good to hear backwards compatibility is being explored/considered, and I just wanted to add my +1 request for it.

While undesirable, I do think it is OK for us to work around & deal with the lack of backwards compatibility of Apple frameworks. The community/devs can build wrappers, reimplement some things and provide fallbacks for most of those things. However, if the language becomes the problem, there is nothing we can do but wait several years, which is extremely sad, given how cool, useful & convenient the Swift concurrency is :frowning_face:


On the face of it, I’m not sure how serious the technical limitations are if people have been able to use it with toolchains before WWDC?

What is the runtime support that is required? it seems from what I've watched so far it seems like a one to one with completion handlers?

Generally backward deployment is a problem for Swift. Google seems to manage this on Android with Kotlin.

1 Like

Well, AFAICT it would require a new runtime, and the implication of shipping Swift runtime with the OSes has been noted before, albeit more generally:

Can I choose to bundle a newer Swift runtime with my apps going forward to be able to use new runtime features without requiring a new OS?

This will not be possible for a number of reasons: [...]

Is there anything that can be done to allow runtime support for new Swift features to be backward deployed to older OSes?

It may be possible for some kinds of runtime functionality to be backward deployed [...] The Core Team will consider the backward deployment implications of new proposals under review on a case-by-case basis going forward.

but they're not ruling this out as impossible, if that's what you want.

If you compile a project a particular toolchain, you gotta make sure there's a supported runtime installed on the target machine as well.

But I digress, this thread isn't really about ABI stability. And they probably already received feedbacks that some places would like back-deploy.


First off, thank you a million to the Swift team for implementing this!

This would be invaluable for us to be able to use these features immediately with the new Swift version. Many companies cannot just drop the last OS version when the new iOS comes out.

So, I'd like to just add a +1 to backwards compatibility for async/await.


That's not going to work IMO as it requires the users to have updated, and the gating of the #available goes well beyond the version number and would have to be changed to be feature based.

The updates need to be shipped as a library/bodge with the app that 'polyfills' the features onto older runtimes. ISTR that early Swift did this with the whole runtime to get working on devices before it stabilised and got bound to the OS - seems like we need to go backwards a bit to move forwards.


Then we need to decouple Swift apps/versions from the system as well - making new Swift features bind to (and only to) the latest OS release in a specific year is not going to work for the language long term.


In order to decouple Swift from OS versions, we would have to give up on Swift OS APIs. Libraries like Combine and SwiftUI would have to be shipped with the apps instead of the OS. This isn’t impossible, but the implications go way beyond the Swift team’s sphere of influence.


In an ideal world, I think the Swift runtime (and updated versions of Apple Frameworks) could be updated on demand on Apple platforms, similar to how Rosetta works on Apple Silicon Macs. i.e. the first time a user tries to download an app from the App Store requiring Swift x.y, the OS could download it as required (and hot-swap the existing system-wide frameworks/runtimes). Not saying this is even feasible at all, just an idea :)


No, it isn't one-to-one with completion handlers. The key difference is that functions that take a completion handler typically return immediately and the completion handler is triggered later (though you can't assume that the completion handler isn't called before the function returns; in some cases, for instance if results are already available, for instance from a cache, it might be).

With an async function, it won't return until execution gets to a return statement, falls off the end of the function, or the function throws. Instead, when an async function does an await, the thread it's on is freed up to do other work (i.e. other async functions may resume execution, and on the main thread/actor, the application's main run loop will run so that the UI remains responsive).

I think the frustration here is because we've waited years for Swift concurrency and now it's here most developers in the real world who are not indie or work for Apple won't be able to use it and will have to wait more years knowing that any concurrency code they write now with closures etc is already technical debt.

It's also frustrating that other platforms like Android are able to update system components out-of-band, why Apple has never done this baffles me. It should't be a surprise that developers are disappointed every year at WWDC when new APIs comes out that we can't use.


I still have a little hope because this is listed in the "Known issues" section of Xcode 13 beta:

Known Issues

  • Swift Concurrency requires a deployment target of macOS 12, iOS 15, tvOS 15, and watchOS 8 or newer. (70738378)

If it doesn't support old versions, it will finally hurt the future of Swift itself.

We've waited for several years until so-called ABI stability. But now this is happening again in a considerably worse form: there's no way to bundle Swift stdlib to have backport support.


Agreed, but I wouldn't mind this at all — it's much easier to ask users on older devices that can't upgrade to the latest and greatest because their devices don't support iOS 15 to upgrade to a version that's available to them (especially if it comes with security improvements).

It definitely does complicate #available, but at this point from what we've been hearing so far adjusting #available sounds like it might be easier than the Swift team having to figure out how to backport features so that Swift devs can actually use them on a reasonable timescale.

1 Like

@matt-curtis I agree the 'ship an update to previous OS versions' is better than the current proposal. I just don't see it happening.

Going back to shipping the language runtime with the app is what has to happen, as appears to be the case on non-Apple platforms. With app thinning Apple should be able to deploy it to only those devices that need it, or, as indicated in Swift.org - Evolving Swift On Apple Platforms After ABI Stability

" Will an app built with Swift 5 run on any version of macOS before 10.14.4?

Swift 5 does not require apps to raise their minimum deployment target.

Apps deploying back to earlier OS releases will have a copy of the Swift runtime embedded inside them. Those copies of the runtime will be ignored — essentially inert — when running on OS releases that ship with the Swift runtime."

then there are 'inert' runtimes on those platforms that already support the features.


Looking at this from the business perspective I think features like this one aren’t created just for the internal development team but rather to improve quality of all software running on Apple platforms. Requiring this year’s OS release for this feature to work would mean that most apps will start adopting this in a few years from now.

I think it would make a lot of sense to add support for this feature (or significant subset) to apps running on earlier iOS versions (or subset if it was easier) also if the performance would be worse. Most businesses don’t need the best performing code but they require support of older operating systems.


That's not a bad idea, you upload your app with the latest runtime embedded, Apple apply app thinning to remove the runtime and create a binary variant which is used when users download in the AppStore on devices that already have the latest or minimum required runtime, all other users (minority) get the slightly larger non-thinned binary containing the runtime.


A lot of the focus here is on the developer implications of whether or not features like this get back ported. Makes sense, that's our jam, but I would argue that the user implications are more important.

Suppose you're the owner of a Mid-2014 13" MacBook Pro. MacOS Monterey drops support for this device. Unless a third party patcher becomes available, you'll be stuck on Big Sur. It's been 7 years, so that seems reasonable. Look at some of the impacts of that:

  • You won't get the new "Focus" features. (that's okay, you still have DnD)
  • Third party apps won't have access to the Focus-related APIs (they'll have to disable related features, or fallback to something else)
  • Third party apps won't have access to Swift concurrency (third party developers will need to ... ???)

One of these is not like the other. It's not like we're missing dark mode, or some theme change, or an isolated feature that can be chopped off with if #available. We're talking about a low-level, prevailing source code feature that's impossible (for practical purposes) to conditionally use.

There's a diversity dimension that I'm particularly concerned about: economic status. It's one whose importance seems (to me) to be clear as day, but I don't really see anyone championing for it. We forget that most people aren’t cycling their expensive tech like us, as though they were some baller annual subscription service. Indeed, iPhone software longevity is a large selling feature, and a competitive advantage of the platform compared to the fragmented Android ecosystem. Moves that go against this just end up being anti-poor (intentionally or not), obsoleting older/second-hand devices.

I can remember a few instances on other platforms (particularly Android) where a single release had so many improved APIs/features that they caused a major turning point. Companies with a policy of say, supporting 3 years back, made exceptions and ended up only supporting 2 years back, just to rush to get to this good stuff.

Every time that happens, we (the dev community) form a thundering herd that leaves poor users behind. We should make sure there's a good reason for it, and I think it's important to do whatever we can to not force the hand of third party devs to drop support for OSes. If Java/Mono/Go could figure this out, I think we should, too.

Terms of Service

Privacy Policy

Cookie Policy