swiftswiftuixcode16

Xcode conditional code based on availability of @Previewable macro


I am writing a Swift package that can be used by either Xcode 15 or Xcode 16. The package code includes SwiftUI previews using inline @State properties. My code:

@available(iOS 17.0, *)
struct ColorPickerView: View {

    @Binding var selectedColor: Color
    
    var body: some View {
        selectedColor
    }
}

@available(iOS 17.0, *)
#Preview {
    @State var selectedColor = Color.blue
    
    return ColorPickerView(selectedColor: $selectedColor)
}

In Xcode 16, I see the following warning:

@State used inline will not work unless tagged with @Previewable

To fix the warning in Xcode 16, I can take the recommendation and add @Previewable, however, this will not compile in Xcode 15.

@available(iOS 17.0, *)
#Preview {
    @Previewable @State var selectedColor = Color.blue
    
    return ColorPickerView(selectedColor: $selectedColor)
}

Is there a way to conditionally compile to detect the availability of @Previewable? In the past, we could check the Swift version or use canImport to perform such conditional compiles. #ifdef replacement in the Swift language. Btw, I also can't find a single new framework available in iOS 18 (e.g. #if canImport(AppleIntelligence)) to use as a proxy for detecting @Previewable availability.


Solution

  • If you're ok with disallowing previews in older versions, you can use #if compiler like so to disable previews in older versions (where 6 is the version of the swift compiler version):

    #if compiler(>=6)
    #Preview {
        @Previewable @State var someVar = true
    ...
    
    }
    #endif