Best way to implement new feature for old SDKs

Swift has the wonderful ability to check for availability of certain methods or properties.

Now if I use temporaryDirectory on NSFileManager for example I can only do so from macOS 10.12 and above.

Now if I want to implement the same property on NSFileManager for older versions, I can only (afaict) do this:

extension FileManager {

var tempDirectory: URL {
    if #available(macOS 10.12, *) {
        return temporaryDirectory
    } else {
        return URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
    }
}

and use my custom property everywhere.

What I would like though would be to have this extension only apply to macOS < 10.12 and then I can name my property exactly temporaryDirectory like on newer versions. And I don't need to use my custom name anywhere.

Is there a better way of achieving this? For example a condition to include code only if !(OS >= x)

Similar question goes for full blown classes like implementing my own ISO8601DateFormatter for older systems.

1 Like

The difference between #if and if #available is that the former is a compile-time check and the latter is a run-time check. If you only build your app once for all deployment targets, you need a run-time check. So no, there is not a better way to do this in today's Swift.

Are there actually ideas how that could work in the future? :slight_smile:

Heh. I did put that in there deliberately, but no, not that I know of. There's nothing incredibly technically difficult in making this work:

@dynamicallyAvailableBefore(macOS 10.12)
var temporaryDirectory: URL { … }

and having the compiler check that the signature matches up and everything before generating the code you wrote above. But it'd be a proposal that needs a lot of careful thought—how does this affect how people use framework code? What happens on new platforms? What if two people do this?

1 Like