Skip to content

Instantly share code, notes, and snippets.

@czottmann
Last active August 9, 2023 09:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save czottmann/a9996c5bb3acbad3d3d3c6dcefb0b967 to your computer and use it in GitHub Desktop.
Save czottmann/a9996c5bb3acbad3d3d3c6dcefb0b967 to your computer and use it in GitHub Desktop.
A macOS 13+ `AppIntent` showcasing weird behaviour for list properties containing only a single `TransientAppEntity`

Test setup

Shortcuts app, add new workflow.

  • First action: "TransientAppEntity Weirdness Showcase"
  • Second action: "Get Items from List" with setting "First Item"

Test 1

  1. Enter 2 as the Item count.
  2. "Get Items from List" action: Select the [String] property
  3. Run workflow: Result is "hello 0" (i.e. the first item in the list stored in that property)
  4. "Get Items from List" action: Now select the [WeirdnessShowcaseAppEntity] property
  5. Run workflow: Result is "hello 0" (i.e. the first item in the list stored in that property)

Test 2

  1. Enter 1 as the Item count.
  2. "Get Items from List" action: Select the [String] property
  3. Run workflow: Result is "hello 0" (i.e. the first item in the list stored in that property)
  4. "Get Items from List" action: Now select the [WeirdnessShowcaseAppEntity] property
  5. Run workflow: Shortcuts displays an error "There was a problem running the shortcut"

What am I missing here? How can I make the property containing the TransientAppEntity behave correctly, i.e. just like the one holding the String?

import AppIntents
import Foundation
/// The `TransientAppEntityWeirdnessShowcase` intent below returns a `TransientAppEntity` (named
/// `ReturnValueAppEntity`) containing two properties: one is a `[String]`, the other is a
/// `[WeirdnessShowcaseAppEntity]`. I expect both to behave the same but they do not:
///
/// If the item count is set to 1, `stringItems` returns a list while `taeItems` returns the single
/// list item by itself, thus breaking any follow up actions expecting a list. If the item count is
/// 2 or more, both return lists.
@available(macOS 13.0, *)
struct TransientAppEntityWeirdnessShowcase: AppIntent {
static var title: LocalizedStringResource = "TransientAppEntity Weirdness Showcase"
static var description = IntentDescription("")
@Parameter(title: "Item count")
var count: Int
static var parameterSummary: some ParameterSummary {
Summary("Return \(\.$count) items each in this action's result properties")
}
func perform() async throws -> some IntentResult & ReturnsValue<ReturnValueAppEntity> {
let rv = ReturnValueAppEntity()
rv.stringItems = (0 ..< count).map { "hello \($0)" }
rv.taeItems = (0 ..< count).map { _ in
let e = WeirdnessShowcaseAppEntity()
e.string = "hello"
return e
}
return .result(value: rv)
}
}
struct ReturnValueAppEntity: TransientAppEntity {
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "ReturnValueAppEntity")
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "ReturnValueAppEntity")
}
@Property(title: "[String]")
var stringItems: [String]
@Property(title: "[WeirdnessShowcaseAppEntity]")
var taeItems: [WeirdnessShowcaseAppEntity]
init() {}
}
struct WeirdnessShowcaseAppEntity: TransientAppEntity {
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "WeirdnessShowcaseAppEntity")
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "WeirdnessShowcaseAppEntity")
}
@Property(title: "Some string value")
var string: String
init() {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment