Array of AppEnum in a Parameter will always be empty

Consider the following in an AppIntent:

struct TestIntent: AppIntent {
    static let title: LocalizedStringResource = "Test Intent"
    static var parameterSummary: some ParameterSummary {
        Summary("Test") {
            \.$options
        }
    }

    enum Option: Int, CaseIterable, AppEnum {
        case one
        case two
        case three
        case four
        case five
        case six

        static let typeDisplayRepresentation: TypeDisplayRepresentation =
            TypeDisplayRepresentation(
                name: "Options"
            )

        static let caseDisplayRepresentations: [Option: DisplayRepresentation] = [
            .one: DisplayRepresentation(title: "One"),
            .two: DisplayRepresentation(title: "Two"),
            .three: DisplayRepresentation(title: "Three"),
            .four: DisplayRepresentation(title: "Four"),
            .five: DisplayRepresentation(title: "Five"),
            .six: DisplayRepresentation(title: "Six"),
        ]
    }

    @Parameter(title: "Options", default: [])
    var options: [Option]

    @MainActor
    func perform() async throws -> some IntentResult {
        print(options)
        return .result()
    }
}

In Shortcuts, this will turn into a dropdown where you can check multiple Option values. However, when perform() is called, options will be an empty array regardless of what the user selects. This is observed on both iOS 18.5 and macOS 15.5. However, on iOS 26.0 beta and macOS 26.0 beta, the issue seems to be resolved and options contains all the checked options. However, we do back deploy to current/previous iOS/macOS versions. How can we provide a multiple choice selection of fixed values on these older versions?

Before jumping to working around this for iOS 18, consider if you need to since it is addressed on iOS 26 — will this intent and parameter be used often? Or are you building a feature with this intent that has a more limited use or audience? Overall update rates for iOS are generally fairly high, so you may find its better to leave the code as it is and increasing numbers of people simply won't encounter the issue as they update to iOS 26 after its release.

I've looked to see if there's something you could do through a DynamicOptionsProvider, but that is showing the same issue as your code example when using the AppEnum on iOS 18. I do see [String] work as the parameter type, so as an idea, perhaps you could use a DynamicOptionsProvider that vends [String] of known fixed string values that you are able to map to your intended values.

A different idea would be to simply expand the cases in the enum if the number of values isn't too high — each new enum case would represent a combinations of values, and then you don't need the Parameter to be an array.

— Ed Ford,  DTS Engineer

Hi Ed, thank you for the response. Unfortunately, the feature will be more used on macOS than iOS and we have observed a slower update rate on macOS.

Expanding the number of options isn't viable because we have 6 options and wish to support all possible combinations which means 6!=720 options.

I will look into [String] but is there a good way to support both [String] on older versions and [Enum] for newer versions in a maintainable way?

Expanding the number of options isn't viable because we have 6 options and wish to support all possible combinations which means 6!=720 options.

I was afraid of that factorial explosion, thanks for showing it will matter to you.

I will look into [String] but is there a good way to support both [String] on older versions and [Enum] for newer versions in a maintainable way?

One thing you could do would be to have 2 separate intents, one of which conforms to DeprecatedAppIntent. The deprecated intent would be the [String] version, and the other one the [Enum] version. Deprecation here is the API mechanism you have to mark actions in Shortcuts as deprecated, so as your users upgrade, they are informed of the path forward, the same way that API deprecations can tell you to replace a deprecated function with its newer replacement. From a clean maintenance point of view, you have an intent for the future, and at a time that works for you in your app's direction over time, you can just delete the deprecated intent's code, or at least freeze its implementation for compatibility purposes and only invest in the non-deprecated version.

The alternative would be to have one intent with 2 parameters, and to try and decipher the combinations across the two different parameters — they set String A and C with Enum B and deciding how to handle that — which of course could bring you back to some tricky combinatorics for the number of options. Some validation code could trim the complexity of the implementation, where you only accept String values or Enum values but never a mix of the two, so this basically comes down to implementation details that you have to assess and see if the simplicity or complexity that would result is acceptable to you.

— Ed Ford,  DTS Engineer

Array of AppEnum in a Parameter will always be empty
 
 
Q