Justified concerns about the consequences of ABI stability?

Right. The only restriction we're looking at is that post-5.0 language and library features that require concrete runtime or library support may not be back-deployable to 5.0.

Obviously, that restriction isn't ideal. For example, I think it would be really unfortunate if you couldn't use async/await until you were willing to bump your deployment target to 6.0 or whenever we ship that. It may be possible to ship stubbed-in support for certain features on older operating systems. But that sort of thing is non-trivial to test and support, and we don't want to promise to do it for literally everything added to the language.


Does this imply that changes/additions to Swift ABI in master may require a beta version of macOS using that Swift ABI to build with, at least if you're wanting to link against system frameworks?

If so, how will that work with developers external to Apple? Changes to the Swift project happen faster than macOS betas, so will external developers be stuck building an old version of master until the next beta comes out?


I will have to recompile my app using the Swift 5 compiler (in Swift 4 mode) though? Because if I use the Swift 4 compiler, the standard library provided by the OS won’t be compatible?

Just to clarify a little more. Will apps written in Swift 3 (that is not supported by the compiler anymore) will work on an OS that comes with the Swift 5 runtime?

What's the relationship between SWIFT_VERSION (the language version) and, for an iOS app, IPHONEOS_DEPLOYMENT_TARGET?

For example, my current IPHONEOS_DEPLOYMENT_TARGET is 10. I want to use the new String interpolation API in Swift 5. So I set the SWIFT_VERSION to 5.0. Can I still ship my app to iOS 10 users since the new String API isn't limited by the OS?

Existing compiled apps using pre-stable versions of the Swift libraries will continue to work. Through a number of mechanisms, we arranged for stable Swift and pre-stable Swift runtimes to be mutually ignorant of each other, so that they can only interact through the common ground of Objective-C interfaces. To Swift code in the OS, pre-stable Swift classes look like plain Objective-C classes, and vice versa. (This arrangement however relies on the fact that, prior to ABI-stable Swift, all pre-stable Swift code in a process had to be self-contained in an app bundle, so would not work to allow for bundled Swift runtimes in the future once there is Swift code shipping in the OS as well.)


If your app is compiled with the Swift 4/4.2 compiler (that is, #if compiler(>=5) is false), then it will continue to use the Swift 4/4.2 runtime packaged with it. As Joe said, the stable Swift runtime is designed to tolerate being in the same process as older Swift runtimes.

If your app is compiled with the Swift 5 compiler in Swift 4 mode (#if compiler(>=5) is true), then it will use the stable Swift runtime in the OS. It will also be packaged with a copy of the stable Swift runtime for older OSes, but that won't be used on OSes that have a stable Swift runtime built in, and it might even be deleted by app thinning.

What some people have asked in this thread is whether you could ship a modified stable Swift runtime with your app and have it use that instead of the one in the OS. The answer is "no". If your app is compiled with Swift 5+ and you run it on a platform with a Swift runtime in the OS, you need to use the runtime in the OS.

In Swift 5, the Swift version and deployment target aren't related, so you can use the new string interpolation API on iOS 10. If we had reworked string interpolation in Swift 5.1 or 6, you might not be able to do that. (Which is part of why string interpolation was reworked in Swift 5 instead of Swift 5.1 or 6.)


For the sake of example, lets say string interpolation was reworked in Swift 5.1 or Swift 6. What's the reason for not being able to use it and deploy back to iOS 10?

If I was to guess, I'd say it is because the ABI the string interpolation API is depends upon doesn't exist in earlier Swift runtimes/binaries.

Thanks to you all for your generous patience as I keep bashing away at my keyboard on this topic.

The idea of not being able to use async/await until I can convince an org to set iOS 13/14 as minimum deployment target makes me incredibly sad :/... <faces real world of many apps still with customers on iOS 9.x>...


Which sorta leads me back to my original frustration: for language, library and compiler improvements that do not depend on the OS, I'd rather bundle things in my app instead of waiting years for my customer base to adopt a specific iOS version and writing years worth of tech debt or :poop: code.

1 Like

Well, going beyond language runtime support, a feature like async/await would also need adoption across the platform APIs to be useful, so even if we manage to backward deploy the language support, it seems to me like getting the full benefit would require targeting a new OS with updated platform libraries.


It's a little more complicated for string interpolation because we already had string interpolation, but we wanted to redesign it. If we tried to rework string interpolation in Swift 6, we would have faced a couple of difficulties:

  • There's already code in the wild using the old APIs, so we'll need to leave them in place. That might mean using different names for the new APIs to avoid conflicting with the old ones.
  • When we generate code for deployment targets that don't have the new APIs, we'll need to work around the fact that they aren't there. How do we do that? It's probably workable, but it's not trivial.

These kinds of backwards compatibility concerns don't apply to additive changes; our availability checker will just require you to include an appropriate version test if you want to use the new stuff. For example, we can add new appendInterpolation overloads in Swift 6, and you'll just need to use @available or #available if you want to use them. Redesigns of existing features are harder.

1 Like

I would very much disagree to say that async/await is not useful outside of Apple's APIs (which is the logical conclusion of "to be useful it needs…").

Of course it will be great to have Cocoa APIs use it but not being able to use async/await in my own code for years to come is a horrible horrible tradeoff and I imagine something most people don't realize.

When this feature is released, almost no one will be able to actually use it in their apps then for years. You can't easily guard against os version and use async/await in one path and callbacks etc. on another so this is very different than just ignoring newer API in an app.

So while ABI lockdown is beneficial for platform vendors like Apple, it seems to have a huge negative impact for everyone else and I'd say even the language itself. I am baffled why this is not being made a bigger deal out of by the developers here. Maybe I am very much wrong and being too dramatic.

Is there no way to mitigate this? A way to ship a newer runtime with the app?


I personally always update my code to the latest Swift release to be able to use new features and improve our product and the codebase itself. Not being able to use latest Swift version for lets say some new generic feature like parameterized extensions, which would reduce my codebase in half, just because our product is targeting iOS 10 would be a disaster. Convincing your org to up the deployment target in order to use a new feature will always result in the same answer, “no“ because that way we would lose many customers. For that one reason I would probably hate the ABI forever.

I‘d rather break the ABI and care a few megs more in the app bundle but that would make my app shiny and my codebase way better and maintainable than with these ABI quirks.

That said, I‘m not flaming here, just saying what ABI lockdown can potentially mean for my work.

You also have to keep in mind that to be able to use a new feature that requires a new OS isn‘t as simple as it sounds. In terms of iOS it could potentially mean that you‘ll be forced to skip not just a single major release but many more. If I want a feature that is introduced in Swift with iOS 14 but the min. target is still iOS 10, well then you probably don‘t even need propose that feature in first place, because I and many other developers won‘t be able to use it for half a decade anyway. :cry:


I just wanted to say that this thread is of the uttermost importance for Swift developers who work in the ecosystem of Apple devices. Yet it's somewhat difficult to gather all pieces of information that are splattered here.

To core team and compiler developers: our concern, as iOS/macOS/etc developers, is to know the consequences of the release of Swift 5 and the advent of ABI stability on our support for our beloved users. Precisely speaking, what is the impact of the target operating system on the versions of the compiler we can use, and/or the version of the language we can use?

For us, it is important to frame the question in this way. That is because the target operating system, the minimum OS on which our apps are supposed to run, is often an input (it is as much a business decision as a technical decision, and we can not always choose it).


Can sombody explain to me in ELI5 style what ABI stability provides in actual practical benefits that caused it to be so important now that it had to be done and could not be postponed into much later in the future. What i heard is a) "its a sign of maturity" b) "code size reduction". There must be something that i am missing here because those two are not reason enough to lose the evolution flexibility i assume.

What am i missing here ?

I agree. It wasn’t clear to me until this thread progressed that it isn’t clear what the answer is. As others have noted, it will be really unfortunate if we are now required to wait years to adopt new Swift features on real world projects which must run on older OS releases.

According to the usual rules of the community, it really seems like the consequences of ABI stability for app developers should have been made clear from the outset of the Swift 5 cycle and discussed as part of an evolution proposal in order to asses the impact on all Swift users. However, just as minimum OS is an input for our teams I suspect that reaching ABI stability within some timeframe was an input for the Swift team in order to allow Apple to start shipping Swift frameworks in the OS. In reality, there probably wasn’t a choice available to be made by the community.

Personally, I wish the language had matured a bit further before declaring ABI stability as we still don’t have first class concurrency support, there are still unfortunate limitations in the generics system, there are still unresolved design issues in the standard library, etc. On the other hand, I am really looking forward to seeing what kind of Swift frameworks Apple ships now that they will be able to do that.


The primary benefit for most current Swift users is that Apple will be able to ship Swift frameworks in the OS. This means Apple platforms will (probably) receive new APIs and frameworks that are designed from the ground up for Swift, possibly even without Objective-C support of any kind. It will be very exciting to see what is announced at WWDC this year!


One question that just was on my mind. In the past years rushing towards ABI stability I've seen tons of answers like "this does not affect ABI". Do all these answers also implied that we'd get backwards deployment of these features for older OS's if compiled with latest Swift version, or was it a strict technical answer?

I personally want to the see the final 'completing generics' happen that isn't forcing me to up min. deployment target. I mean, this was one goal of Swift in the early days (even before ABI stability direction?), but in the current state it's still far from being finished!

1 Like

I've asked before with no response, where is/was the evolution proposal for ABI stability? How can such a major change enter the language without going through the defined change process?

ABI stability was a goal for Swift well before the open source project and evolution process even began (some may remember, it was claimed as a goal and then postponed for every Swift release, including 2, 3, 4, and 4.2, so we've hardly "rushed in" to it), so it's "grandfathered in" and was never subject to evolution. I can understand all of your desire for a definitive document describing the impact of ABI stability on the language and standard library going forward. I'll forward this concern to the core team.