Does anyone know if there is a way to import a Swift Package with a minimum deployment target greater than the the target project? The idea would be to use any API within the package behind gated availability checks. Is this possible yet?
This is not possible. (And I always advise anyone tempted to set deployment targets to think again.) Your only option right now is to fork the dependency and convert its deployment targets into
@available conditions throughout its source files.
As I find myself having to do this more and more often, I have considered writing a tool that automates “fixing” a package in this manner (still in a fork though). But the annoyance hasn’t quite crossed the threshold where it is worth it yet. On the other hand, if there are others out there who want such a tool badly enough to be willing to help develop and support it, then I might be convinced to start it sooner.
I wonder if there’s a proposal to lift this constraint. Packages should be able to include dependencies with higher minimum targets than their own, but implicitly mark the contents with an availability check within the context of the target.
Under the hood it would have to do basically same thing as the hypothetical tool above, (which would make a working version of such a tool more‐or‐less a prerequisite of a proposal, because that would be more or less the bar of proof that it can be done reliably).
You cannot just tell it to build the two modules at different minimum targets, because setting a minimum target causes the compiler to skip all runtime checks needed by anything lower. That means when the top module tries to load the dependency at runtime, it just crashes, because it needs stuff that doesn’t exist at load time, not just during execution of the guarded code paths. (The system libraries do not need to worry about this only because they have no transitive dependencies of their own that are outside their control.)
You also cannot just override the dependency’s minimum target in the build instructions, because then it will fail to compile. Fixing that compile failure involves annotating everything with availability guards. That is where the tool would fit in, regardless of whether it remained separate or became integrated into SwiftPM.
I’d be in favour of a proposal that included the tool above if that’s the simplest way to achieve this. I think the net result is that it should feel invisible to the package consumer.
The current situation of package maintainers marking their minimum targets as low as possible and then manually marking @available everywhere isn’t ideal.
If that change was made, then what would be the point of a package declaring a minimum deployment target in the first case? What meaning would it have?
It would allow the package to build against a base availability just like it does now. The suggestion would allow consumers to not be constrained by the package’s target, it wouldn’t change anything for the package itself.