Skip to content

Add an option to fallback on Backport when first-party native API is not available? #68

@edonv

Description

@edonv

Describe the feature

A new public EnvironmentValue (and optionally a public-facing ViewModifier) that enables or disables internal use of the first-party APIs that this package backports when running on a device where it's available?

Is your feature request related to a problem?

Something I find myself doing when using SwiftUIBackports is creating local modifiers and views that check the OS version (#available) and return the native API when it's available and fallback on this package's backports for older OS'es. It'd be super awesome if this could be added as a built-in feature.

Proposed solution

A private EnvironmentKey of type Bool. Maybe the KeyPath for EnvironmentValues would be called something like \.preferNativeAPIWhenAvailable (which would be set to true when the developer wants to use the first-party API when the device is on an OS version that supports the native API). This could also be confusing because it doesn't refer to SwiftUIBackports in the name, so it might not be clear its purpose (aside from good documentation). Or it could be called \.preferBackportOnNewerOS, which would make its value imply the opposite.

This could also be implemented in SwiftBackports.

Additional context

An example of my current solution (which I'm suggesting be implemented in SwiftUIBackports) is as follows:

struct BackportNavigationLink<P: Hashable, Label: View>: View {
    var value: P?
    var label: () -> Label
    
    @ViewBuilder
    var body: some View {
        if #available(iOS 16, *) {
            NavigationLink(value: value, label: label)
        } else {
            Backport.NavigationLink(value: value, label: label)
        }
    }
}

The only difference in the implementation would be this:

struct BackportNavigationLink<P: Hashable, Label: View>: View {
    @Environment(\.preferBackportOnNewerOS)
    private var preferBackportOnNewerOS
    
    var value: P?
    var label: () -> Label
    
    @ViewBuilder
    var body: some View {
        if #available(iOS 16, *), !preferBackportOnNewerOS {
            NavigationLink(value: value, label: label)
        } else {
            Backport.NavigationLink(value: value, label: label)
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions