Conditional Compilation inside array initializer

I want something like this:

import SwiftUI

let screens: [AnyView] = [
    #if os(iOS)
    AnyView(TextFieldPlay()),
    #endif
    AnyView(PickerPlay()),
    AnyView(ViewSizingPlay()),
    AnyView(ProgressBarPlay()),
    AnyView(HalfRoundedPlay()),
    AnyView(MultiBarPlay()),
    AnyView(ClockFacePlay()),
    AnyView(BlurPlay()),
    AnyView(DnDPlay()),
    AnyView(ColorPatchPlay()),
    AnyView(CanvasPlay()),
    AnyView(SKPlay())
]

But no go, Xcode complains that "Consecutive statements on a line must be separated by ';' ", so clearly it's getting terminally confused.

I get a similar message if I try if #available, which really is no surprise.

Is there any pretty way to do this?

Also, if anyone wanted to offer suggestions about the array itself, it'd be welcome. The program uses the array to populate a navigation grid. I really wish it could be an array of View but that never worked out.

Right now, not really. I think I'd go for something like this, which is quite a bit more verbose:

let lol: [String] = {
    var a = [
        "a",
    ]
    #if SOME_CONDITION
    a += ["x"]
    #endif
    a += ["y"]
    return a
}()

In the long run, the next revision of SE-0330 is our best hope.

1 Like

Or, if you are okay with using something that might look a bit confusing to newcomers to your code base, you can use a result builder, something like this:

@resultBuilder struct ArrayBuilder<T> {
    static func buildBlock(_ components: T...) -> [T] { components }
}

extension Array {
    init(@ArrayBuilder<Element> builder: () -> [Element]) { self.init(builder()) }
}

Array {
    "a"
    #if KERN_KDEBUG
    "c"
    #endif
    "b"
}
1 Like

That's tempting just for fun, but in the end I went with this:

let screens: [AnyView] = {
    var theSet: [AnyView] = []
    #if os(iOS)
    theSet.append(AnyView(TextFieldPlay()))
    #endif
    
    theSet.append (contentsOf: [
        AnyView(PickerPlay()),
        AnyView(ViewSizingPlay()),
        AnyView(ProgressBarPlay()),
        AnyView(HalfRoundedPlay()),
        AnyView(MultiBarPlay()),
        AnyView(ClockFacePlay()),
        AnyView(BlurPlay()),
        AnyView(DnDPlay()),
        AnyView(ColorPatchPlay()),
        AnyView(CanvasPlay()),
        AnyView(SKPlay())
    ])
    return theSet
}()

1 Like