@available support for stored properties - Is it possible?

Recently I came across an example of where it would be nice to use @available on a stored property (specifically a wrapped one).

This SwiftUI view which is built for iOS 13+ doesn't compile

struct BorderlessButton: View {
    @available(iOS 14, *)
    @Environment(\.accessibilityShowButtonShapes) private var _showButtonShapes

    private var showButtonShapes: Bool {
        if #available(iOS 14, *) {
            return _showButtonShapes
        } else {
            return false
        }
    }
}

'accessibilityShowButtonShapes' is only available on iOS 14 or newer
The diagnostic here shows that the @available isn't respected for property wrapper inputs, but that's not the root of the issue.

struct BorderlessButton: View {
    @available(iOS 14, *)
    private var _showButtonShapes = false

    private var showButtonShapes: Bool {
        if #available(iOS 14, *) {
            return _showButtonShapes
        } else {
            return false
        }
    }
}

Stored properties cannot be marked potentially unavailable with '@available'

I was hoping code like this would be possible, because the alternative is a lot of boilerplate for this property.

private struct _BorderlessButton: View {
    let showButtonShapes: Bool

    ...
}

private struct iOS13BorderlessButton: View {
    var body: some View {
        _BorderlessButton(showButtonShapes: false)
    }
}

@available(iOS 14, *)
private struct iOS14BorderlessButton: View {
    @Environment(\.accessibilityShowButtonShapes) private var showButtonShapes
    var body: some View {
        _BorderlessButton(showButtonShapes: showButtonShapes)
    }
}

struct BorderlessButton: View {
    var body: some View {
        if #available(iOS 14, *) {
            iOS14BorderlessButton()
        } else {
            iOS13BorderlessButton()
        }
    }
}

So the question now, is marking stored properties with @available something that could be possible?

I don't know much about the inner workings of the Swift runtime, but my thought is that for structs(maybe classes too) when initializing the properties you could avoid initializing properties that aren't available and you would be left with an uninitialized chunk of memory. The memory is there to ensure that the struct is the same size when the same binary is running on different OS versions. This uninitialized memory would be safe because the normal availability checks would apply for if you could access the memory. That's my thought at least, was hoping someone with more knowledge in the area could tell me if this is even possible.

4 Likes