'SwiftUI preview crashes when extending View

I have a project that needs to support an old version of iOS and I'm trying to use SwiftUI for a view that will only appear when the user is on iOS 13 or later. The SwiftUI Preview in Xcode works just fine, but when I extend a SwiftUI struct (such as View), the project will compile and run on a device, but the Preview Canvas crashes, stating that it Failed to build myView.swift. When I click on the "diagnostics" button, it tells me that 'View' is only available in iOS 13.0 or newer and add @available attribute to enclosing extension. However, the extension in question already has @available(iOS 13.0, *) before it. For example:

@available(iOS 13.0, *)
extension View {
    func myFunc() {

    }
}

In an effort to find the root of this problem, I noticed that the preview won't crash if it's completely empty. Only once I add a function or static property to it will the canvas crash. I have also tried adding the @available line before each function in the extension, rebooting my computer, and deleting the DerivedData folder, but it doesn't seem to have made a difference.



Solution 1:[1]

Discussion

The following code example works well for me. Please note the @available(iOS 13.0, *) declaration attributes for not only the View extension, but also for:

  1. The ContentView struct, which conforms to the View protocol,

and

  1. The ContentView_Previews struct, which conforms to the PreviewProvider protocol.

FYI: I set my Xcode Project's deployment target to iOS 12.4 for my test.

Code Example

import SwiftUI

@available(iOS 13.0, *)
extension View {
    func overlayText<Content>(_ content: Content) -> some View where Content : StringProtocol {
        overlay(Text(content))
    }
}

@available(iOS 13.0, *)
struct ContentView: View {
    static private var initialGreeting = "Hello World!"
    static private var greetings: [String] {
        [
            initialGreeting,
            "Hey Everyone!",
            "Hi Everybody!",
            "Hello Friends!"
            
        ]
    }
    @State private var greeting = initialGreeting
    
    var body: some View {
        Button(action: { [greeting] in
            while self.greeting == greeting {
                self.greeting = Self.greetings.randomElement()!
            }
        }) {
            Color.green
                .overlayText(greeting)
                .cornerRadius(30)
                .padding(5)
        }
        .background(Color.black)
        .frame(height: 50)
        .foregroundColor(.white)
        .font(.system(size: 28, weight: .bold))
        .cornerRadius(30)
        .padding()
    }
}

@available(iOS 13.0, *)
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jeremy Pearson