Function Back Deployment(github.com)
github.com
Function Back Deployment
https://github.com/apple/swift-evolution/blob/main/proposals/0376-function-back-deployment.md
8 comments
I think you're confused (or I'm mistakenly confident).
@available is, indeed, when something was actually introduced. As you put it, "available to use starting with this version."
@backDeployed is for when something could've worked on an earlier version, if you just copied and pasted the function body. So something that has relatively straightforward logic, doesn't change the layout of or introduce new structs, etc.
Then when you build the project, the compiler can figure out if it can just use the library's version of the function (target >= @available) or if it needs to copy over the definition itself (@backDeployed <= target < @available). But from your perspective as a consumer of the function, you can act like it's been present since the version indicated in @backDeployed.
@available is, indeed, when something was actually introduced. As you put it, "available to use starting with this version."
@backDeployed is for when something could've worked on an earlier version, if you just copied and pasted the function body. So something that has relatively straightforward logic, doesn't change the layout of or introduce new structs, etc.
Then when you build the project, the compiler can figure out if it can just use the library's version of the function (target >= @available) or if it needs to copy over the definition itself (@backDeployed <= target < @available). But from your perspective as a consumer of the function, you can act like it's been present since the version indicated in @backDeployed.
The 'proposed solution':
I would have expected `@available(toasterOS 2.0, *)` indicating this was not implemented until 2.0, followed by `@backDeployed(toasterOS 1.0` indicating it's also available to this earlier version.
Please correct me where I've gone wayward.
My proposal would be `@available(toasterOS VersionOlderThanCurrent)` indicating this is available for use in that older version, and an optional `@developedWith(toasterOS CurrentVersion)`
Edit: you say
> @available is, indeed, when something was actually introduced. As you put it, "available to use starting with this version."
Let me be clear in my intent: I read the linked article as saying @available is "I implemented this using version X", and I always thought it was "this will [only] work on version X (or later?)" regardless of when it was actually written. These have different meanings - that is my intent.
extension Toaster {
@available(toasterOS 1.0, *)
@backDeployed(before: toasterOS 2.0)
public func makeBatchOfToast(_ breadSlices: [BreadSlice]) -> [Toast] { ... }
}
So it was introduced in 1.0, right? Then why do I need an annotation saying "you can use this before 2.0?" This is where I'm confused. If this example is not a mistake, the purpose of @backDeployed is not clear to me.I would have expected `@available(toasterOS 2.0, *)` indicating this was not implemented until 2.0, followed by `@backDeployed(toasterOS 1.0` indicating it's also available to this earlier version.
Please correct me where I've gone wayward.
My proposal would be `@available(toasterOS VersionOlderThanCurrent)` indicating this is available for use in that older version, and an optional `@developedWith(toasterOS CurrentVersion)`
Edit: you say
> @available is, indeed, when something was actually introduced. As you put it, "available to use starting with this version."
Let me be clear in my intent: I read the linked article as saying @available is "I implemented this using version X", and I always thought it was "this will [only] work on version X (or later?)" regardless of when it was actually written. These have different meanings - that is my intent.
It means `makeBatchOfToast()` is available from toasterOS1.0. So if you are running toasterOS0.5 you are out of luck.
If you are targeting toasterOS1.0, `@backDeployed` will ensure that the function that is copied to your binary is used. For toasterOS2.0 and above, the function provided by the linked framework will be used.
Huh, turns out I was mistakenly confident about my own understanding after all! Suraj provides a correct explanation as a sibling comment :)
So some stuff got released without an annotation system that declares when it's available, and this let's folks use that on old versions? How big of a problem is this?
Unlike Android where Jetpack tries it’s hardest to backport new libraries to old OS, Apple almost always required consumers to upgrade to new OS to use their latest libraries.
If this means Apple is more likely to let me use SwiftUI iOS 17 features when targeting iOS 16 devices, it’s pretty exciting.
If this means Apple is more likely to let me use SwiftUI iOS 17 features when targeting iOS 16 devices, it’s pretty exciting.
Sounds like this will specifically allow for older devices to continue to work with newer versions of apps. Obviously not everything will work, but it would still be nice to be able to use some old i-device even if it can't run the latest iOS.
I never knew that was the intended use. I thought it was “available (to use) starting with (version)”
Edit: reading further, the example is backward from what I would have intuitively expected from the author’s arguments. So they’re advocating for using @available the way I thought it was used, and adding @backDeployed to indicate when it was added? I find this confusion and unnecessary.