Will Swift Concurrency deploy back to older OSs?

After just watching the excellent WWDC session by @Ben_Cohen (Swift concurrency: Update a sample app - 10194) its been made very obvious that by not having the ability to back-port Swift concurrency by even a single major iOS version is a multiplying problem across the industry.

Let's take our team of 15 iOS devs as an example. We currently support iOS 13 as our minimum deployment target and have over 220k swift LOC in the app. The minimum deployment target is dictated by our users upgrade behaviour, so as it stands we won't be able to drop iOS 14 until iOS 17 is out. In that time a lot more code will be produced that can't adopt Swift concurrency and we are possibly looking at double or more lines being added to our codebase over that time.

The problem is that the more code we add over that time the more time it's going to take us to adopt async/await and the harder sell it's going to be to the business to have time to make those changes. It's been made very obvious in Ben's talk that this isn't going to be a trivial conversion and will take a long time to adopt.

All the time we spend writing code for the next two+ years we know at some point we are going to have to do some major refactoring. So then comes the question; should we just continue to use GCD and pretend swift concurrency doesn't exist for the lifetime of the app? From a business point of view the time we spend actually fixing concurrency issues right now pales in comparison to refactoring the entire codebase to adopt Swift Concurrency in a few years time, and that balance won't actually shift for a long time. This is something that will be echoed across the industry, hence the multiplier I mentioned before.

I think the Swift concurrency features are great and I've personally played with a few of the early snapshots, so it came as quite a surprise that it wasn't being supported on older iOS versions. I have a feeling that we have missed the boat already to get this changed for the release of iOS 15, but it's worth saying that if this could be supported for even 1 previous major iOS version then it is going to save many thousands of hours of developer time over the coming years.


All of your users are able to update to iOS 15 on day 1, so you're in a much better situation than anyone supporting iOS 12 or macOS. macOS is really the big issue here, as the machines last much longer and are more expensive (usually) than mobile devices.


Windows and Linux have nothing to worry about here, as they aren't ABI stable and can easily move to the latest language version whenever they need. It's strictly Apple's platforms where this is a concern, as they include Swift as part of the OS.

Good to know that its an ABI problem. Was afraid that this would became a bigger issue

Need to take a time to update the swift compiler source and see how is this whole concurrency plumbing is going under the hood..

I'm afraid about exactly this, that the user upgrade behaviour can be changed, by holding the developer experience hostage, and weaponizing third-party app support as leverage to entice users to buy new hardware more often.

That's the road I hope we don't keep going down.


I'll throw in my two cents as someone working on a framework: Having a language feature that's only available on the newest OSes is going to be a huge pain, both internally and externally.

We'll likely need to create a secondary library that makes various public APIs available as async/await for people who want to use that, but leaves completion handlers for people who don't. That's a pretty significant maintenance burden.

We'd also love to take advantage of the simplifications and correctness helpers of this internally, but if we can't do that for older OSes, then for all intents and purposes, we can't do that at all. Frankly, I was really looking forward to async/await and its ability to vastly simplify a bunch of our callback-based code, but without some kind of runtime helper we wouldn't be able to do this for years. That's a big disappointment.

It's been mentioned previously, but I do think the Android Support libraries are a good pattern to consider here: They allow backporting of new features to old operating systems, and allow developers to continue to support older OSes while taking advantage of improvements in developer experience included in new ones. You also only have to add the support libraries to your application or framework if your API target is below what's supported natively - once you drop support for older OSes, you can remove that extra code entirely.

Obviously not needing that would be even better, but I'd way rather have an extra library than be unable to use and have to do a ton of extra work to support async/await on older versions.


Back when Swift 5.0 was first announced with ABI stability on Apple platforms, we wrote a blog post outlining some of the reasons the Swift runtime cannot be embedded in apps anymore:

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:

  • The coexistence functionality that is used to maintain compatibility with pre-stable Swift runtimes depends on there being no more than two Swift runtimes active in a single process, and that all Swift code using the pre-stable runtime is self-contained as part of the app. If the same mechanism were used to allow a newer Swift runtime to be bundled to run alongside the OS Swift runtime, the new runtime would have no access to Swift libraries in the OS or ABI-stable third-party Swift libraries linked against the OS runtime.
  • Outright replacing the OS runtime with a bundled runtime would circumvent the security of the system libraries, which are code-signed based on their using the OS version of the runtime.
  • Furthermore, if the OS Swift runtime could be replaced, this would add a dimension to the matrix of configurations that the OS, Swift runtime, and third-party libraries and apps all have to be tested against. “DLL hell” situations like this make testing, qualifying, and delivering code more difficult and expensive.
  • By being in the OS, the Swift runtime libraries can be tightly integrated with other components of the OS, particularly the Objective-C runtime and Foundation framework. The OS runtime libraries can also be incorporated into the dyld shared cache so that they have minimal memory and load time overhead compared to dylibs outside the shared cache. Eventually, it may be impossible for a runtime built outside the OS to fully replicate the behavior of the OS runtime, or doing so may come with significant performance costs when constrained to using stable API.

Hopefully that helps answer some of the questions about why back-deploying concurrency is not a mere matter of bundling a new runtime with old OSes.


With all due respect, this never covered how, why not, etc… the OS component could not be updated outside of the OS updates themselves. It requires a lot of work that could have been spent in other areas and it was sorely needed because as a platform Android is so so fragmented, but Google Play Services being updated and delivering core libraries updates through the Play Store, with more and more OS components delivered through the Play Store too (project Mainline not unlike Treble before it), are not just medicines against fragmentation but a big help to developers overall.

I think this thread could be a good opportunity for bringing these discussions and the compromises (nothing is perfect :)) made along the way forward again: as a dev I see Compose and Kotlin async/await and async sequences (Flow) and I can back deploy to Android 5, while SwiftUI’s latest big updates and async/await in Swift are iOS 15 only. Same thing for WKWebView improvements vs Android System WebView/Chrome WebView (the latter updated on the Google Play Store… ok sometimes causing massive breakages).

I do see also the ugly side of Jetpack libraries approach because the burden is on the dev to figure out how these hundreds of libraries work together (makes updating and dependency management fun). Apple going that far may be a bit of a “Frogs who wished for a king” tale… ;).

This is aside from how it is getting more and more complex to update macOS versions in an Enterprise settings which might bite people when a future Xcode update mandates Monterey next April or May (I worked quite a bit with our IT to get my team updated to Big Sur, the rest of the company aside from few people in IT may have to wait for Monterey as Big Sur was a bigger break for vendors we depend on than I was hoping especially for updates and not clean installs, but sorry this is beside the point… but if Sophos Endpoint Security, Global Protect VPN, Cisco Umbrella/OpenDNS, JAMF, etc… are not bringing memories… well, I am genuinely happy for you :)).


Just to throw my hat in the ring here, I am also in the position of not being able to use anything tied to iOS 15 specifically, for at least two years and maybe longer...

I know it's a hard problem to figure out how to back port this, but being able to do anything (even just part of Swift Concurrency and not the whole thing?) would be welcome, even just to iOS 14 and above would be a great help.

That said this is an important enough change I am considering getting buy-in to ship iOS15 specific versions of an SDK my company publishes, so that all of the interfaces would be Swift Concurrency friendly.


While true, it doesn't mean that they will. There is a long held perception that upgrading will slow down their devices. This is no longer the case for the most part, but it's a hard perception to break. For us as an e-commerce app, we can't simply drop an OS if we have an insignificant number of users using an older version of the OS, our users will simply go elsewhere.

I do feel for anyone who has a lower minimum deployment target than even we do, or even those who support macOS in this situation. We are in a more fortunate position but are still several years away from adopting this technology.

This is pretty much what I thought, and why I realise its probably too late in the day to change/adopt anything before Swift 5.5 drops later this year. It would be nice to see if there are any recommended strategies for the thousands of developers who can't adopt this right now but want to in future?


+1 for backporting concurrency on macOS.

This isn’t just a small quality-of-life improvement to Swift; it’s a fundamental refactoring of how Swift apps are structured.

Asking developers to wait 3 years (on iOS) or 5 years (on macOS) should never have been on the table. The change in the language is too big and too important.

If it’s not backported, we’ll all spend the next few years writing outdated concurrent code because, for all practical purposes, Swift will still lack concurrency.


With all the ABI stability work in place, would it be possible to include the new runtime in a point release? This way, new language features could be used, without having to resort to shims or replacement runtimes and keep all the benefits of one true system runtime.


Isn't the problem due to people not updating, either by choice or by necessity?


policy and technical reasons aside, it seems there is a blurring of os and language that alot of people werent expecting... myself included...


A point update is a much smaller ask that most users don't think about than a major version bump - especially when we're talking about hardware support of the point release version compared to the entire new OS version


I personally have skipped over at least a few major versions of MacOS over the years: Lion, Yosemite, and Sierra. But I have never intentionally skipped a point release.


One point I don’t think I’ve seen raised so far: if concurrency effectively can’t be used in apps for another 3-5 years, it will put those using Swift both in their app and on the server in a really tight spot. If you want to share code between your app and your server, you’ll have to architect things very carefully, or you’ll have your own personal dependency hell as the server ecosystem moves on. That’s not going to be good for the public perception of serverside Swift — after all, one of the best arguments for using Swift on the server is that it’s easy to share code with your app.


There are many devices that cannot update to iOS 13 and I think smaller numbers of devices that can't update to iOS 12 and possibly also some numbers on iOS 11 and 10. If Apple (and I have no idea of the cost of this which would likely be largely in QA) could release point releases for all major versions that have end of support devices I could potentially sell clients on the benefits of a release that will only work if people update but won't absolutely lock out hundreds of thousands of users (we are still supporting iOS 12 currently on several apps).

Obviously this would be a second best to actual backwards support (even if it needed a runtime to be shipped with the app again) for iOS 14 and below. However either approach would allow adoption over the next year rather than probably not before 2023 which is the earliest we could start to migrate any existing apps.

My personal little indie apps are different. I've already started the migration there, the old version should continue to work but updates will only be for iOS 15 and I'd likely have made that change anyway for the latest SwiftUI changes and to avoid having to test across the old version. That just isn't possible in my current professional role where I've only been able to use SwiftUI on one feature so far (conditional compilation and a web view fallback for iOS 12).

Apple, I know it would be a large undertaking (though I don't know how large) but please find a way to support Swift Concurrency on older OSes. This doesn't need to be done from the launch day of iOS 15 though, if an intention and a timeline is announced it could be done late in the year or even into next year. It would still allow much earlier adoption generally. Many libraries won't adopt it while they still need to support the old way


I work in a mid-sized development team that is accustomed to not being able to use new Apple-specific APIs immediately (Combine, SwiftUI etc.) but it came as quite a shock that we probably won’t be able to use the most significant Swift update yet for at least a couple of years.

I understand technically it’s not as simple as “just bundle the runtime” but it certainly seems within the realms of possibility this could have been considered ahead of the iOS 15 release.

knowing all concurrent code we write for the next two years is essentially tech debt whilst the Android guys continue to use coroutines and deploy all the way back to API level 21 leaves a bit of a sour taste.


Without getting into the technical "what about" questions, it is highly disappointing that Apple designed Swift to takes years for devs supporting the App Store to use once it is available. This doesn't even include the years it took to go from proposal to available.

To make an analogy, imagine if Apple said "Here is the new M1X MacBook Pro and it is only available to Windows switchers and Apple employees. This new product will be made available to existing Apple customers to upgrade in 3 years."

This is not an Apple-like experience.


I was going to suggest this as well. I know I usually wait a little bit to install a major version, but I pretty much always install a point release immediately. I think that is pretty common behavior.

I don't think it would need to support the new API, just concurrency primitives. Then people can pretty easily write frameworks and wrappers to make everything work on older systems...

1 Like
Terms of Service

Privacy Policy

Cookie Policy