Share intents from within an app to drive system intelligence and show the app's actions in the Shortcuts app.

Posts under Intents tag

93 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Request array with AppIntents
Hi, I’m trying to get an array of strings from the user using AppIntents, but I’m encountering an issue. The shortcut ends without prompting the user for input or saving the value, though it doesn’t crash. I need to get the user to input multiple tasks in an array, but the current approach isn’t working as expected. Here’s the current method I’m using: // Short code snippet showing the current method private func collectTasks() async throws -> [String] { var collectedTasks: [String] = tasks ?? [] while true { if !collectedTasks.isEmpty { let addMore = try await $input.requestConfirmation("Would you like to add another task?") if !addMore { break } } let newTask = try await $input.requestValue("Please enter a task:") collectedTasks.append(newTask) } return collectedTasks } The Call func perform() async throws -> some IntentResult { let finalTasks = try await collectTasks() // Some more Code } Any advice or suggestions would be appreciated. Thanks in advance!
0
0
147
1w
Request Array with AppIntent
Hi everyone, i'm trying to request in a AppIntent an array of strings. But I want to give the user the chance to add more than one String. Yet, I do it so: import AppIntent struct AddHomework: AppIntent { // some Parameters @Parameter(title: "Tasks") var tasks: [String]? @Parameter(title: "New Task") //Only for the special request var input: String? private func collectTasks() async throws -> [String] { var collectedTasks: [String] = tasks ?? [] while true { if !collectedTasks.isEmpty { let addMore = try await $input.requestConfirmation(for: "Möchtest du noch eine Aufgabe hinzufügen?") if !addMore { break } } let newTask = try await $input.requestValue("Please enter your task:") collectedTasks.append(newTask) } return collectedTasks } @MainActor func perform() async throws -> some IntentResult { let finalTasks = try await collectTasks() // some more code return .result() } } But this is not working. The Shortcut is ending without requesting anything. But it is not crashing. I would thankfully for some help.
0
0
151
1w
EntityStringQuery does not show variable menu in Shortcuts app
(Public dupe of FB16477656) The Shortcuts app allows you to parameterise the input for an action using variables or allowing "Ask every time". This option DOES NOT show when conforming my AppEntity.defaultQuery Struct to EntityStringQuery: But it DOES shows when confirming to EntityQuery: As discussed on this forum post (or FB13253161) my AppEntity.defaultQuery HAS TO confirm to EntityStringQuery to allow for searching by String from Siri Voice input. To summarise: With EntityQuery: My Intent looks like it supports variables via the Shortcuts app. But will end up in an endless loop because there is no entities(matching string: String) function. This will allow me to choose an item via the Shorcuts.app UI With EntityStringQuery: My Intent does not support variables via the Shortcuts app. I am not allows to choose an item via the Shorcuts.app UI. Even weirder, if i set up the shortcut with using a build with EntityQuery and then do another build with EntityStringQuery it works as expected. Code: /* Works with Siri to find a match, doesn't show "Ask every time" */ public struct WidgetStationQuery: EntityStringQuery { public init() { } public func entities(matching string: String) async throws -> [Station] { let stations = [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")] return stations.filter { $0.id.lowercased() == string.lowercased() } } public func entities(for identifiers: [Station.ID]) async throws -> [Station] { let stations = [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")] return stations.filter { identifiers.contains($0.id.lowercased()) } } public func suggestedEntities() async throws -> [Station] { return [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")] } public func defaultResult() async -> Station? { try? await suggestedEntities().first } } /* DOES NOT work with Siri to find a match, but Shortcuts shows "Ask every time" */ public struct WidgetBrokenStationQuery: EntityQuery { public init() { } public func entities(matching string: String) async throws -> [Station] { let stations = [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")] return stations.filter { $0.id.lowercased() == string.lowercased() } } public func entities(for identifiers: [Station.ID]) async throws -> [Station] { let stations = [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")] return stations.filter { identifiers.contains($0.id.lowercased()) } } public func suggestedEntities() async throws -> [Station] { return [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")] } public func defaultResult() async -> Station? { try? await suggestedEntities().first } }```
0
0
148
2w
INUIHostedViewControlling ViewController's Life Cycle Events not being Called
I am implementing a new Intents UI Extension and am noticing that the viewWillDisappear, viewDidDisappear, and deinit methods are not being called on my UIViewController that implements INUIHostedViewControlling, when pressing the "Done" button and dismissing the UIViewController. This causes the memory for the UI Extension to slowly increase each time I re-run the UI Extension until it reaches the 120MB limit and crashes. Any ideas as to what's going on here and how to solve this issue? Worth noting that while the memory does continuously increase on iOS versions before iOS 17, only in 17 and later does the 120MB memory limit kick in and crash the extension.
2
0
290
3w
Custom Intent ParameterSummary based on Widget Kind/ID
I'm trying to create two widgets, widget A and B. Currently A and B are very similar so they share the same Intent and Intent Timeline Provider. I use the Intent Configuration interface to set a parameter, in this example lets say its the background tint. On one of the widgets, widget A, I want to also set another String enum parameter (for a timescale), but I don't want this option to be there for widget B as it's not relevant. I'm aware of some of the options for configuring the ParameterSummary, but none that let me pass in or inject the "kind" string (or widget ID) of the widget that's being modified. I'll try to provide some code for examples. My Widget Definition (targeting >= iOS 17) struct WidgetA: Widget { // I'd like to access this parameter within the intent let kind: String = "WidgetA" var body: some WidgetConfiguration { AppIntentConfiguration(kind: kind, intent: WidgetIntent.self, provider: IntentTimelineProvider()) { entry in WidgetView(data: entry) } .configurationDisplayName("Widget A") .description("A widget.") .supportedFamilies([.systemMedium, .systemLarge]) } } struct WidgetB: Widget { let kind: String = "WidgetB" var body: some WidgetConfiguration { AppIntentConfiguration(kind: kind, intent: WidgetIntent.self, provider: IntentTimelineProvider()) { entry in WidgetView(data: entry) } .configurationDisplayName("Widget B") .description("B widget.") .supportedFamilies([.systemMedium, .systemLarge]) } } struct IntentTimelineProvider: AppIntentTimelineProvider { typealias Entry = WidgetIntentTimelineEntry typealias Intent = WidgetIntent ........ } struct WidgetIntent: AppIntent, WidgetConfigurationIntent { // This intent allows configuration of the widget background // This intent also allows for the widget to display interactive buttons for changing the Trend Type static var title: LocalizedStringResource = "Widget Configuration" static var description = IntentDescription("Description.") static var isDiscoverable: Bool { return false} init() {} init(trend:String) { self.trend = trend } // Used for implementing interactive Widget func perform() async throws -> some IntentResult { print("WidgetIntent perform \(trend)") #if os(iOS) WidgetState.setState(type: trend) #endif return .result() } @Parameter(title: "Trend Type", default: "Trend") var trend:String // I only want to show this parameter for Widget A and not Widget B @Parameter(title: "Trend Timescale", default: .week) var timescale: TimescaleTypeAppEnum? @Parameter(title: "Background Tint", default: BackgroundTintTypeAppEnum.none) var backgroundTint: BackgroundTintTypeAppEnum? static var parameterSummary: some ParameterSummary { // Summary("Test Info") { // \.$timescale // \.$backgroundTint // } // An example of a configurable widget parameter summary, but not based of kind/ID string When(\.$backgroundTint, .equalTo, BackgroundTintTypeAppEnum.none) { Summary("Test Info") { \.$timescale \.$backgroundTint } } otherwise : { Summary("Test Info") { \.$backgroundTint } } } } enum TimescaleTypeAppEnum: String, AppEnum { case week case fortnight static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Trend Timescale") static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [ .week: "Past Week", .fortnight: "Past Fortnight" ] } enum BackgroundTintTypeAppEnum: String, AppEnum { case blue case none static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Background Tint") static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [ .none: "None (Default)", .blue: "Blue" ] } I know I could achieve what I'm after by having a separate Intent and separate IntentTimelineProvider for each widget. But this all seems unnessecary for just a simple optional parameter based on what widget its configuring.... unless I'm missing the point about Intents, Widgets or something! I've done a fair bit of other searching but can't find an answer to this overall scenario. Many thanks for any help.
1
0
234
Jan ’25
How to remove INSendMessageIntent in Shortcuts app?
I’ve implemented an Intent Extension and added support for handling the INSendMessageIntent in the intent handler class. Currently, this intent is automatically visible in the Shortcuts app by default. However, for security reasons (as it involves handling phone numbers), I want to restrict the use of this intent to Siri only and ensure it does not appear in the Shortcuts app. Has anyone encountered this requirement before or knows a way to prevent the intent from appearing in the Shortcuts app, while still keeping it functional via Siri? Looking forward to your suggestions!
1
1
205
Jan ’25
INUIHostedViewControlling ViewController's Life Cycle Events not being Called
I am implementing a new Intents UI Extension and am noticing that the viewWillDisappear, viewDidDisappear, and deinit methods are not being called on my UIViewController that implements INUIHostedViewControlling, when pressing the "Done" button and dismissing the UIViewController. This causes the memory for the UI Extension to slowly increase each time I re-run the UI Extension until it reaches the 120MB limit and crashes. Any ideas as to what's going on here and how to solve this issue?
2
0
255
Jan ’25
get location in app intent for interactive widgets
I have an app intent for interactive widgets. when I touch the toggle, the app intent perform to request location. func perform() async throws -> some IntentResult { var mark: LocationService.Placemark? do { mark = try await AsyncLocationServive.shared.requestLocation() print("[Widget] ConnectHandleIntent: \(mark)") } catch { WidgetHandler.shared.error = .locationUnauthorized print("[Widget] ConnectHandleIntent: \(WidgetHandler.shared.error!)") } return .result() } @available(iOSApplicationExtension 13.0, *) @available(iOS 13.0, *) final class AsyncLocationServive: NSObject, CLLocationManagerDelegate { static let shared = AsyncLocationServive() private let manager: CLLocationManager private let locationSubject: PassthroughSubject<Result<LocationService.Placemark, LocationService.Error>, Never> = .init() lazy var geocoder: CLGeocoder = { let geocoder = CLGeocoder() return geocoder }() @available(iOSApplicationExtension 14.0, *) @available(iOS 14.0, *) var isAuthorizedForWidgetUpdates: Bool { manager.isAuthorizedForWidgetUpdates } override init() { manager = CLLocationManager() super.init() manager.delegate = self } func requestLocation() async throws -> LocationService.Placemark { let result: Result<LocationService.Placemark, LocationService.Error> = try await withUnsafeThrowingContinuation { continuation in var cancellable: AnyCancellable? var didReceiveValue = false cancellable = locationSubject.sink( receiveCompletion: { _ in if !didReceiveValue { // subject completed without a value… continuation.resume(throwing: LocationService.Error.emptyLocations) } }, receiveValue: { value in // Make sure we only send a value once! guard !didReceiveValue else { return } didReceiveValue = true // Cancel current sink cancellable?.cancel() // We either got a location or an error continuation.resume(returning: value) } ) // Now that we monitor locationSubject, ask for the location DispatchQueue.global().async { self.manager.requestLocation() } } switch result { case .success(let location): // We got the location! return location case .failure(let failure): // We got an error :( throw failure } } // MARK: CLLocationManagerDelegate func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { defer { manager.stopUpdatingLocation() } guard let location = locations.first else { locationSubject.send(.failure(.emptyLocations)) return } debugPrint("[Location] location: \(location.coordinate)") manager.stopUpdatingLocation() if geocoder.isGeocoding { geocoder.cancelGeocode() } geocoder.reverseGeocodeLocation(location) { [weak self] marks, error in guard let mark = marks?.last else { self?.locationSubject.send(.failure(.emptyMarks)) return } debugPrint("[Location] mark: \(mark.description)") self?.locationSubject.send(.success(mark)) } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { locationSubject.send(.failure(.errorMsg(error.localizedDescription))) } } I found it had not any response when the app intent performed. And there is a location logo tips in the top left corner of phone screen.
2
0
325
Jan ’25
Siri Shortcuts Response Templates No work on iOS18.1.1
I have shortcuts up and running and I have my custom response added to my completion handler since day1. Recently I upgraded to iOS18, and found out the app I develop can not display the custom response. I test the app on iOS17.6, the display of custom response is no problem. The situation is exactly like the problem posted on 2018: https://forums.developer.apple.com/forums/thread/109324 Can anyone help me or have the same bugs? Thank you so much! Happy 2025
1
0
244
Jan ’25
Inform iOS about AppShortcutsProvider
I've been following along with "App Shortcuts" development but cannot get Siri to run my Intent. The intent on its own works in Shortcuts, along with a couple others that aren't in the AppShortcutsProvder structure. I keep getting the following two errors, but cannot figure out why this is occurring with documentation or other forum posts. No ConnectionContext found for 12909953344 Attempted to fetch App Shortcuts, but couldn't find the AppShortcutsProvider. Here are the relevant snippets of code - (1) The AppIntent definition struct SetBrightnessIntent: AppIntent { static var title = LocalizedStringResource("Set Brightness") static var description = IntentDescription("Set Glass Display Brightness") @Parameter(title: "Level") var level: Int? static var parameterSummary: some ParameterSummary { Summary("Set Brightness to \(\.$level)%") } func perform() async throws -> some IntentResult { guard let level = level else { throw $level.needsValueError("Please provide a brightness value") } if level > 100 || level <= 0 { throw $level.needsValueError("Brightness must be between 1 and 100") } // do stuff with level return .result() } } (2) The AppShortcutsProvider (defined in my iOS app target, there are no other targets) struct MyAppShortcuts: AppShortcutsProvider { static var shortcutTileColor: ShortcutTileColor = .grayBlue @AppShortcutsBuilder static var appShortcuts: [AppShortcut] { AppShortcut( intent: SetBrightnessIntent(), phrases: [ "set \(.applicationName) brightness to \(\.$level)", "set \(.applicationName) brightness to \(\.$level) percent" ], shortTitle: LocalizedStringResource("Set Glass Brightness"), systemImageName: "sun.max" ) } } Does anything here look wrong? Is there some magical key that I need to specify in Info.plist to get Siri to recognize the AppShortcutsProvider? On Xcode 16.2 and iOS 18.2 (non-beta).
5
0
706
Jan ’25
AppIntents: Shortcuts phrases with parameters are not resolving correctly
Exploring AppIntents and Shortcuts. No matter what I try Siri won't understand parameters in an initial spoken phrase. For example, if I ask: "Start my planning for School in TestApp", Siri responds: "What's plan?", I say: "School" and Siri responds "Ok, starting Shool plan" What am I missing so it won't pick up parameters right away? Logs inside func entities(matching string: String) are only called after "What's plan?" question and me answering "School". No logs after the initial phrase Tried to use Apple's Trails example as a reference but with no luck
1
0
306
Dec ’24
Xcode 16.x project doesn’t build with (SiriKit / Widget) intent definition file + translations
If you add a (SiriKit / Widget) intent definition file to an Xcode project and then translate it into another language, the build of the iOS app only works until you close the project. As soon as you open the project again, you get the error message with the next build: Unexpected duplicate tasks A workaround for this bug is, that you convert the folder (where the intent file is located) in Xcode to a group. After that every thing works without problems. Steps to reproduce: Create a new iOS project Add a localization to the project (German for example) Add a SiriKit Intent Definition File Localize the SiriKit Intent Definition File Build the project (should work without errors) Close the project Open the project again Build the project again Expected result: The project builds without problems Current result: The project doesn’t build and returns the error: Unexpected duplicate tasks Is this a known problem? Is there a way to solve this without switching to Xcode groups (instead of folders)
3
1
411
Dec ’24
How to use a Decimal as @Property of AppEntity
I’m trying to use a Decimal as a @Property in my AppEntity, but using the following code shows me a compiler error. I’m using Xcode 16.1. The documentation notes the following: You can use the @Parameter property wrapper with common Swift and Foundation types: Primitives such as Bool, Int, Double, String, Duration, Date, Decimal, Measurement, and URL. Collections such as Array and Set. Make sure the collection’s elements are of a type that’s compatible with IntentParameter. Everything works fine for other primitives as bools, strings and integers. How do I use the Decimal though? Code struct MyEntity: AppEntity { var id: UUID @Property(title: "Amount") var amount: Decimal // … } Compiler Error This error appears at the line of the @Property definition: Generic class 'EntityProperty' requires that 'Decimal' conform to '_IntentValue'
1
0
431
Dec ’24
Intents not showing up in WatchOS Shortcuts
I have developed a standalone WatchOS app which runs a stopwatch. I want to develop a shortcut that launches the stopwatch. So far I have created the Intent file, and added the basic code (shown below) but the intent doesn't show in the shortcuts app. In the build, I can see the intent metadata is extracted, so it can see it, but for some reason it doesn't show in the watch. I downloaded Apple's demo Intent app and the intents show in the watch there. The only obvious difference is that the Apple app is developed as an iOS app with a WatchOS companion, whereas mine is standalone. Can anyone point me to where I should look for an indicator of the problem? Many thanks! // // StartStopwatch.swift // LapStopWatchMaster import AppIntents import Foundation struct StartStopWatchAppIntent: AppIntent { static let title: LocalizedStringResource = "Start Stopwatch" static let description = IntentDescription("Starts the stopwatch and subsequently triggers a lap.") static let openAppWhenRun: Bool = true @MainActor func perform() async throws -> some IntentResult { // Implement your app logic here return .result(value: "Started stopwatch.") } }
3
0
391
Dec ’24
Parametrized Shortcuts do not show up in Shortcuts app and search with localisation.
Hi! When my device is set to English, both search and the Shortcuts up automatically show multiple shortcuts parametrised for each value of the AppEnum - which is what I expected. When my device is set to German, I get only the basic AppShortcut without the (optional) parameter. I am using an AppEnum (see below) for the parametrised phrases and localise the phrases into German with an AppShortcuts String Catalog added to my project. Everything else seems to work, I can use my AppShortcut in the Shortcuts app and invoke it via Siri in both English and German. The Shortcuts app displays the values correctly using the localized strings. Any ideas? import AppIntents class ApolloShortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: GetIntent(), phrases: [ "Get data from \(.applicationName)", "Get data from \(.applicationName) for \(\.$day)", "Get data from \(.applicationName) for the \(\.$day)" ], shortTitle: "Get Data", systemImageName: "wand.and.sparkles") } } enum ForecastDays: String, AppEnum { static var typeDisplayRepresentation: TypeDisplayRepresentation = "Day" static var caseDisplayRepresentations: [Self : DisplayRepresentation] = [ .today: DisplayRepresentation(title: LocalizedStringResource("today", table: "Days")), .tomorrow: DisplayRepresentation(title: LocalizedStringResource("tomorrow", table: "Days")), .dayAfterTomorrow: DisplayRepresentation(title: LocalizedStringResource("dayAfterTomorrow", table: "Days")) ] case today case tomorrow case dayAfterTomorrow var displayName: String { String(localized: .init(rawValue), table: "Days") } }
1
0
362
Nov ’24
Handle InSendMessageIntent in the app
Hi, I'm implementing InSendMessageIntent handling in our app. I can handle InSendMessageIntent through extension, but handling also includes business logic like authorisation status and some heavy operation which I can't expose from the main target. I tried to handle it in-app, but func application(_ application: UIApplication, handlerFor intent: INIntent) -> Any? didn't trigger. At the first glance the configuration looks correct - the InSendMessageIntent is added under INIntentsSupported and UIApplicationSupportsMultipleScenes is set to YES in info.plist. After that reply with message button disappeared from the incoming Voip callKit screen. So I had a question - Is this intent possible to be handled in-app?
0
0
346
Nov ’24
Localized App Shortcuts phrases don't work with AppIntents consumed from a Framework
Imagine we have an Xcode workspace containing two projects: MyLibrary.xcodeproj holding a framework target MyShortcutsApp.xcodeproj holding an app target which consumes MyLibrary framework Both targets define App Intents and the ones from MyLibrary are exposed via AppIntentsPackage accordingly. When trying to wrap the App Intent from framework as App Shortcut and passing localized AppShortcutPhrases I do see the following compile error: ".../Resources/de.lproj/AppShortcuts.strings:11:1: error: This AppShortcut does not map to a known action (MyLibraryIntent specified). (in target 'MyShortcutsApp' from project 'MyShortcutsApp')" If I use the same localized App Shortcut phrases for an App Intent which is locally defined in the app target, everything works fine and also if I use the framework-provided App Intent in and App Shortcut without passing any localized phrases. This is happening with Xcode 16.0 (16A242d), with 16.1 (16B40) and with 16.2 beta 2 (16C5013f). I already raised this issue via FB15701779 which contains a sample project to reproduce and to further analyze the issue. Thanks for any hint on how to solve that. Frank
1
4
542
Dec ’24
Shortcuts not appearing in Shortcuts.app
I'm curious if anyone else has figured out why an intent defined in the intents file never seems to appear in the Shortcuts app on MacOS. I'm following the steps outlined in "Meet Shortcuts for MacOS" from WWDC 2021. https://developer.apple.com/videos/play/wwdc2021/10232 I build and run my app, launch Shortcuts, and the intent I defined refuses to show up! There's one caveat - I allowed Xcode to update to 16.1, and mysteriously the intent became available in Shortcuts.app. When I went to add a second intent, I see the same as above - it simply never shows up in Shortcuts.app. I have a few intents I'd like to write/add, but this build/test cycle is really slowing me down. This app is a completely fresh Swift-AppKit app, I've never archived it, so there shouldn't be more than one copy on disk. I have also cleaned the build folder, restarted Xcode, restarted Shortcuts, restarted my machine entirely... Anyone see this before and find a workaround? Any advice on how to give Shortcuts.app a kick in the rear to try and find my second intent?
1
0
350
Nov ’24