I’m developing an iOS app using the App Intents framework. I’ve created an ‘OpenShowIntent’ that should allow users to open a show from outside the app by either:
Invoking a shortcut and providing a show name, or
Asking Siri: ‘Open [show name] in [app name]’
The shortcut works correctly when invoked manually through the Shortcuts app. However, when I try to use the Siri voice command, Siri recognizes the app name but doesn’t seem to capture the show name. Siri loads but then doesn’t complete the action and return “Something went wrong”. What might be the problem here?
OpenShowIntent.swift:
import Foundation
import AppIntents
import Models
@available(iOS 16.0, *)
struct OpenShowIntent: AppIntent {
static var title: LocalizedStringResource = "Open a Show"
static var openAppWhenRun = true
@Parameter(title: "Show", optionsProvider: ShowEntityQuery())
var show: ShowEntity?
@Parameter(title: "Show Name")
var showName: String
static var parameterSummary: some ParameterSummary {
Summary("Open (.$showName) in (APP NAME)")
}
@MainActor
func perform() async throws -> some IntentResult & ProvidesDialog {
var showToOpen: ShowEntity
if let show = show {
showToOpen = show
} else {
let params = ElasticSearchParams(query: showName)
let searchResults = try await IntentsHelper.getShows(searchParams: params)
let entities = searchResults.map { show in
ShowEntity(id: show.id, name: show.displayName, posterUrl: show.posterImageUrl)
}
showToOpen = try await $show.requestDisambiguation(
among: entities,
dialog: "Choose a show from this list?"
)
}
let deepLink = DeepLink(
type: .show(
showId: showToOpen.id,
showDateStr: nil,
voucher: nil,
reviewModalParams: nil
)
)
let url = try deepLink.createURL(source: nil)
IntentsHelper.openLink(url: url)
return .result(dialog: "Show '(showToOpen.name)' opened successfully.")
}
}
ShowEntity.swift:
import Foundation
import AppIntents
import Models
@available(iOS 16.0, *)
struct ShowEntity: AppEntity {
typealias DefaultQuery = ShowEntityQuery
var id: Int
var name: String
var posterUrl: URL?
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Show"
var displayRepresentation: DisplayRepresentation {
var image: DisplayRepresentation.Image?
if let imageUrl = posterUrl {
image = DisplayRepresentation.Image(url: imageUrl)
}
return DisplayRepresentation(
title: LocalizedStringResource(stringLiteral: name),
subtitle: nil,
image: image
)
}
static var defaultQuery = ShowEntityQuery()
init(id: Int, name: String, posterUrl: URL?) {
self.id = id
self.name = name
self.posterUrl = posterUrl
}
}
ShowEntityQuery.swift:
import Foundation
import AppIntents
import Models
@available(iOS 16.0, *)
struct ShowEntityQuery: EntityStringQuery {
func entities(for identifiers: [Int]) async throws -> [ShowEntity] {
let params = ElasticSearchParams(showIds: identifiers)
let searchResult = try await IntentsHelper.getShows(searchParams: params)
return searchResult.map { show in
ShowEntity(id: show.id, name: show.displayName, posterUrl: show.posterImageUrl)
}
}
func suggestedEntities() async throws -> [ShowEntity] {
let params = ElasticSearchParams(
showIds: BookmarksManager.sharedManager.getBookmarkShowIdsAsArray()
)
let searchResult = try await IntentsHelper.getShows(searchParams: params)
return searchResult.map { show in
ShowEntity(id: show.id, name: show.displayName, posterUrl: show.posterImageUrl)
}
}
func entities(matching query: String) async throws -> [ShowEntity] {
let params = ElasticSearchParams(query: query)
print("entities(matching:) called with query: (query)")
let searchResult = try await IntentsHelper.getShows(searchParams: params)
return searchResult.map { show in
ShowEntity(id: show.id, name: show.displayName, posterUrl: show.posterImageUrl)
}
}
}
ShortcutsProvider.swift:
import Foundation
import AppIntents
@available(iOS 16.0, *)
struct TTShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
return [
AppShortcut(
intent: OpenShowIntent(),
phrases: [
"View show in (.applicationName)",
"Open (.$showName) in (.applicationName)",
"Show (.$showName) in (.applicationName)",
"Find (.$showName) in (.applicationName)",
"Search for (.$showName) in (.applicationName)"
],
shortTitle: "Open show",
systemImageName: "pencil.circle"
)
]
}
static var shortcutTileColor: ShortcutTileColor = .blue
}
I want the user to activate siri and tell “Open {showname} in {appName}” and Siri will open the show in the app.
user26425844 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.