I need to have a dynamic parameter for Shortcuts, so a person can say something like
Hey Siri, order a pizza with
The parameter code in the appIntent is
@Parameter(title: "Title")
var itemName: String
In the Shortcut I use:
AppShortcut(
intent: NewItemIntent(),
phrases: [
"order \(\.$itemName) using \(.applicationName)"
],
shortTitle: "Order Item",
systemImageName: "sparkles"
)
When I call it "hey Siri, order pizza using ***" where pizza should be passed via the parameter then handed off to the appintent. However, it ignores the spoken parameter in lieu of putting up a dialog asking "What's the name?" I can say "pizza" and it now works. How can I pick up the parameter without having to go to that second step as the code implies?
App Intents
RSS for tagExtend your app’s custom functionality to support system-level services, like Siri and the Shortcuts app.
Posts under App Intents tag
192 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm developing an AppIntent with a Duration parameter, the definition looks like this:
@Parameter(title: "Duration", description: "Time entry duration")
var duration: Measurement<UnitDuration>
When I run this AppIntent using Siri voice command (by a shortcut) the system asks for the duration value, however when I try to say "1 hour 10 minutes" the "hour" component is ignored, in the AppIntent's perform() method I see only the minutes set (so in this case only 10 minutes).
Is there any way to use the Duration type for this type of natural language input?
When I try to set only 10 minutues, or 1 hour separately it works, just the combination of these two fails.
Thank you
I have a custom intent. When my app is unable to complete the resolution of a parameter within the app extension, I need to be able to continue within the app. I am unable to figure out what the correct objective C syntax is to enable the execution to continue with the app. Here is what I have tried:
completion([[PickWoodIntentResponse init] initWithCode:PickWoodIntentResponseCodeContinueInApp userActivity:nil]);
This results in the following error:
Implicit conversion from enumeration type 'enum PickWoodIntentResponseCode' to different enumeration type 'INAnswerCallIntentResponseCode' (aka 'enum INAnswerCallIntentResponseCode')
I have no idea why it is referring to the enum type of 'INAnswerCallIntentResponseCode' which is unrelated to my app.
I have also tried:
PickWoodIntentResponse *response = [[PickWoodIntentResponse init] initWithCode:PickWoodIntentResponseCodeContinueInApp userActivity:nil];
completion(response);
but that results in 2 errors:
Implicit conversion from enumeration type 'enum PickWoodIntentResponseCode' to different enumeration type 'INAnswerCallIntentResponseCode' (aka 'enum INAnswerCallIntentResponseCode')
and
Incompatible pointer types passing 'PickWoodIntentResponse *' to parameter of type 'INStringResolutionResult *'
The relevant autogenerated code provided to me with the creation of my intent is as follows:
@class PickWoodIntentResponse;
@protocol PickWoodIntentHandling <NSObject>
- (void)resolveVarietyForPickWood:(PickWoodIntent *)intent withCompletion:(void (^)(INStringResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveVariety(for:with:)) API_AVAILABLE(ios(13.0), macos(11.0), watchos(6.0));
@end
typedef NS_ENUM(NSInteger, PickWoodIntentResponseCode) {
PickWoodIntentResponseCodeUnspecified = 0,
PickWoodIntentResponseCodeReady,
PickWoodIntentResponseCodeContinueInApp,
PickWoodIntentResponseCodeInProgress,
PickWoodIntentResponseCodeSuccess,
PickWoodIntentResponseCodeFailure,
PickWoodIntentResponseCodeFailureRequiringAppLaunch
}
@interface PickWoodIntentResponse : INIntentResponse
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithCode:(PickWoodIntentResponseCode)code userActivity:(nullable NSUserActivity *)userActivity NS_DESIGNATED_INITIALIZER;
@property (readonly, NS_NONATOMIC_IOSONLY) PickWoodIntentResponseCode code;
@end
Am I overlooking something? What would be the proper syntax to have within the completion block to satisfy the compiler?
I have an iOS app that connects to a server running on macOS by leveraging NWListener & NWBrowser. It also makes use of the peerToPeer functionality / AWDL offered via the Network framework. This works great in the iOS app. Now I would like to add support for Shortcuts / App Intents in general.
The NWConnection on its own is also working great in the App Intent, but only if I provide the host/port manually, which means I can't use the peer to peer functionality. If I try to run my NWBrowser in the AppIntent it immediately changes its state to failed with a NoAuth (-65555) error:
nw_browser_cancel [B1517] The browser has already been cancelled, ignoring nw_browser_cancel().
nw_browser_fail_on_dns_error_locked [B1518] DNSServiceBrowse failed: NoAuth(-65555)
NWClientManager: Browser failed: -65555: NoAuth
I haven't found documentation/information on whether NWBrowser should work in an AppIntent extension or not.
In order to make referencing keys for localized strings a little more reliable, our application references generated constants for localized string keys:
This eliminates the potential for developers to misspell a key when referencing a localized strings. And because these constants are automatically generated by the exact same process that provides localized strings for the application, each and every constant is guaranteed to have a localized string associated with it.
I’m currently attempting to implement something similar for the localized strings referenced by our new App Intents. Our initial release of App Intent functionality is simply using string literals to reference localized strings:
However, I am running into several issues when trying to reference the string keys as a constant. The closest I managed to get was defining the constant as either a LocalizationValue or as a StaticString and referencing the constant while initializing the LocalizedStringResource. With this approach, I see no errors from Xcode until I try and compile. What’s more is that the wording of the error being thrown is quite peculiar:
As you can see with the sample code above, I am clearly calling LocalizedStringResource’s initializer directly as Indicated by the error.
Is what I’m trying to do even possible with App Intents? From my research, it does look like iOS app localization is moving more towards using string literals for localized strings. Like with String Catalog’s ability to automatically generate entries from strings referenced in UI without the need for a key. However, we’d prefer to use constants if possible for the reasons listed above.
I have seen some application having custom images in shortcuts app, but after refreing all the apple documentation and source code im yet to figure out a way to show images. the AppShortcutProvider only supports Sfsymbols as of now. then how come other applications is able to do this ? please advice ?
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
Spotlight
Shortcuts
Intents
App Intents
In iOS 18 (beta 1-4) when you set openAppWhenRun = false in your AppIntent of your live activity the perform function never gets called.
In iOS 16 and 17 my live activities work. I have downloaded other apps and in their live activities any button tab which doesn´t open the app is also doing nothing in iOS 18.
Has anyone got this working? Any comments from an Apple engineer on this?
In our widget we include a button with an intent, making a network call to refresh some shared data in its perform(). Whether the call finishes in time or not is not important to us, what matters more is that the widget gets reloaded at the end and displays whatever data it has available with its transition animation.
On iOS18.0 we see the widget being reloaded but on the latest version 18.4 this doesn't happen anymore.
Going through the logs, on both devices we see this same flow:
default 2025-04-10 15:05:26.853674 +0300 WidgetRenderer_Default Evaluating dispatch of UIEvent: 0x300e002a0; type: 0; subtype: 0; backing type: 11; shouldSend: 1; ignoreInteractionEvents: 0, systemGestureStateChange: 0
default 2025-04-10 15:05:26.853691 +0300 WidgetRenderer_Default Sending UIEvent type: 0; subtype: 0; to windows: 1
default 2025-04-10 15:05:26.853702 +0300 WidgetRenderer_Default Sending UIEvent type: 0; subtype: 0; to window: <WidgetRenderer.WidgetWindow: 0x5689b4000>; contextId: 0x8E401B8A
default 2025-04-10 15:05:26.853735 +0300 SpringBoard Evaluating dispatch of UIEvent: 0x300af9420; type: 0; subtype: 0; backing type: 11; shouldSend: 1; ignoreInteractionEvents: 0, systemGestureStateChange: 0
default 2025-04-10 15:05:26.853836 +0300 SpringBoard Sending UIEvent type: 0; subtype: 0; to windows: 1
default 2025-04-10 15:05:26.853864 +0300 SpringBoard Sending UIEvent type: 0; subtype: 0; to window: <_UISystemGestureWindow: 0xb5a20d000>; contextId: 0x5A4C4C23
default 2025-04-10 15:05:26.854862 +0300 SpringBoard Evaluating dispatch of UIEvent: 0x300aeeca0; type: 0; subtype: 0; backing type: 11; shouldSend: 1; ignoreInteractionEvents: 0, systemGestureStateChange: 0
default 2025-04-10 15:05:26.854866 +0300 WidgetRenderer_Default [Timeline[<edited-bundle-identifier>::<edited-bundle-identifier>.<Widget>:widget:systemMedium::321.00/148.00/20.20:(null)]--A76785AED3F9::0xb5bc4c000)] Handle action
default 2025-04-10 15:05:26.854892 +0300 SpringBoard Sending UIEvent type: 0; subtype: 0; to windows: 1
default 2025-04-10 15:05:26.854901 +0300 SpringBoard Sending UIEvent type: 0; subtype: 0; to window: <SBHomeScreenWindow: 0xb5ad60000>; contextId: 0x71D69FA2
default 2025-04-10 15:05:26.855015 +0300 WidgetRenderer_Default Handle action: <private>
default 2025-04-10 15:05:26.855360 +0300 SpringBoard Allowing tap for icon view '<private>'
default 2025-04-10 15:05:26.855376 +0300 SpringBoard Not allowing tap gesture to begin because we're not editing, the custom view controller's user interaction is enabled, and the effective icon alpha isn't zero.
default 2025-04-10 15:05:26.856940 +0300 SpringBoard Icon touch ended: <private>
default 2025-04-10 15:05:26.857474 +0300 backboardd contact 1 presence: none
default 2025-04-10 15:05:26.857826 +0300 chronod Received action <private> for interaction <WidgetRenderSession--4632871937259503361-scene::C1F20222-CC99-45CC-B074-A76785AED3F9::0xb5bc4c000-[<edited-bundle-identifier>::<edited-bundle-identifier>.<Widget>:widget:systemMedium::321.00/148.00/20.20:(null)]>
default 2025-04-10 15:05:26.858381 +0300 chronod [<WidgetRenderSession--4632871937259503361-scene::C1F20222-CC99-45CC-B074-A76785AED3F9::0xb5bc4c000-[<edited-bundle-identifier>::<edited-bundle-identifier>.<Widget>:widget:systemMedium::321.00/148.00/20.20:(null)]>] Handle interaction: <private>
default 2025-04-10 15:05:26.858436 +0300 chronod Pausing reloads for: [<edited-bundle-identifier>::<edited-bundle-identifier>.<Widget>:widget]
default 2025-04-10 15:05:26.869525 +0300 chronod [0xd180b2440] activating connection: mach=true listener=false peer=false name=com.apple.linkd.registry
default 2025-04-10 15:05:26.870054 +0300 WidgetRenderer_Default Evaluating dispatch of UIEvent: 0x300e002a0; type: 0; subtype: 0; backing type: 11; shouldSend: 0; ignoreInteractionEvents: 0, systemGestureStateChange: 0
default 2025-04-10 15:05:26.870124 +0300 SpringBoard Evaluating dispatch of UIEvent: 0x300af9420; type: 0; subtype: 0; backing type: 11; shouldSend: 0; ignoreInteractionEvents: 0, systemGestureStateChange: 0
default 2025-04-10 15:05:26.870198 +0300 SpringBoard Evaluating dispatch of UIEvent: 0x300aeeca0; type: 0; subtype: 0; backing type: 11; shouldSend: 0; ignoreInteractionEvents: 0, systemGestureStateChange: 0
default 2025-04-10 15:05:26.871831 +0300 linkd Accepting XPC connection from PID 129 for service "com.apple.linkd.registry"
default 2025-04-10 15:05:26.871840 +0300 linkd [0x410cbe6c0] activating connection: mach=false listener=false peer=true name=com.apple.linkd.registry.peer[129].0x410cbe6c0
info 2025-04-10 15:05:26.876032 +0300 chronod Client requested (
"<LNFullyQualifiedActionIdentifier: 0xd17321b40, bundleIdentifier: <edited-bundle-identifier>, actionIdentifier: ReloadBalanceIntent>"
), got {
}
default 2025-04-10 15:05:26.877178 +0300 chronod [0xd180b2440] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
default 2025-04-10 15:05:26.877377 +0300 linkd [0x410cbe6c0] invalidated because the client process (pid 129) either cancelled the connection or exited
Then it followa with this on iOS18.4 :
error 2025-04-10 15:21:32.964920 +0300 chronod [<WidgetRenderSession-7817322460413849944-scene::B5E4D7C4-91E1-4656-8175-C3C3C1CB894D::0xc733b8000-[<edited-bundle-identifier>::<edited-bundle-identifier>.<Widget>:widget:systemLarge::364.00/382.00/23.00:(null)~(null)]>] Encountered error when handling interaction: ChronoKit.InteractiveWidgetActionRunner.Errors.runnerClientError(Error Domain=WFLinkActionWorkflowRunnerClientErrorDomain Code=1 "There is no metadata for ReloadBalanceIntent in `<edited-bundle-identifier>`" UserInfo={NSLocalizedDescription=There is no metadata for ReloadBalanceIntent in `<edited-bundle-identifier>`})
default 2025-04-10 15:21:32.964958 +0300 chronod [<edited-bundle-identifier>::<edited-bundle-identifier>.<Widget>:widget] Resuming reloads. Reload state paused -> clean
info 2025-04-10 15:21:32.965013 +0300 chronod [interactionFailed] All diagnostics are disabled.
Whereas on iOS18.0 it follows with a simplified error:
error 2025-04-10 15:05:26.879005 +0300 chronod [<WidgetRenderSession--4632871937259503361-scene::C1F20222-CC99-45CC-B074-A76785AED3F9::0xb5bc4c000-[<edited-bundle-identifier>::<edited-bundle-identifier>.<Widget>:widget:systemMedium::321.00/148.00/20.20:(null)]>] Encountered error when handling interaction: Error Domain=ChronoKit.InteractiveWidgetActionRunner.Errors Code=1
default 2025-04-10 15:05:26.879065 +0300 chronod Resuming reloads for: [<edited-bundle-identifier>::<edited-bundle-identifier>.<Widget>:widget]
but afterwards we see many lines describing the reload process.
So it turns out that the intent fails(?) to execute on both OSes but iOS18.0 triggers a reload even so, which fits our purposes.
What could the issue be? The intent is pretty standard, it contains only the title, localizedDescription and is defined only inside the widget.
We are looking at the possibility of launching our app through Siri with a locked device. We have the device responding to our App Intent but it is asking to be unlocked first. If the device is locked the intent works perfectly. It just doesn't seem to respect the set intentAuthenticationPolicy.
Thank you for you time looking into this.
We have set these var to .alwaysAllowed and open to true.
static var authenticationPolicy: IntentAuthenticationPolicy = .alwaysAllowed
static var openAppWhenRun: Bool = true
Here is our full test code:
import AppIntents
import SwiftUI
// MARK: - App Intents
struct OpenAppIntent: AppIntent {
static var title: LocalizedStringResource = "Open Main App"
static var description: IntentDescription? = .init(stringLiteral: "Opens the App")
static var authenticationPolicy: IntentAuthenticationPolicy = .alwaysAllowed
static var openAppWhenRun: Bool = true
func perform() async throws -> some IntentResult {
print("App opened")
return .result()
}
}
struct TestAppShortcutProvider: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: OpenAppIntent(),
phrases: [
"Begin \(.applicationName)"
],
shortTitle: "Open App",
systemImageName: "popcorn.fill"
)
}
}
I'm adding widget interactivity to my home screen widgets via buttons and AppIntents, but running into some interesting behavior the way the timeline is reloaded after.
I'm following this guide from Apple
https://developer.apple.com/documentation/widgetkit/adding-interactivity-to-widgets-and-live-activities
And the widget is guaranteed to be reloaded when a button pressed with an intent, But whenever the AppIntent is done with the perform action, the widget timeline is always reloaded twice. It's also interesting to note that both reloads happen after the perform method. If you add a 10 second sleep in the perform, nothing happens for 10 seconds, then both reloads happen.
This issue with this is 2-fold.
calculating and rendering the entire widget timeline can be Networking and DB intensive operations, so I would ideally like to avoid doing all the work twice and save the users battery and processing.
The even worse issue, sometimes data on the server changes in between the split second duplicate widget timeline reloads, causing the widget to flash one state, then update to another a second later which is not a good user experience.
I have a sample project which shows the issue and is very easy to reproduce.
The widget simply keeps track of the number of reloads.
To reproduce:
Add the widget to the homescreen
Press the refresh button, and observe the timeline refresh count always goes up by 2.
I've filed a Feedback and attached the sample project and screen recording for anyone to reproduce.
FB15595835
I need to elicit the location of the user in the Siri intents and so I call:
override init(){ super.init() self.locationManager=CLLocationManager() self.locationManager.delegate = self; self.locationManager.startUpdatingLocation() self.locationManager.requestWhenInUseAuthorization() }
Still neither
public func locationManagerDidChangeAuthorization(_ manager: CLLocationManager)
nor
public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
are ever called, notwithstanding the presence of the correct entry in the info.plist, the inclusion of the library and the indication of the delegation with:
class IntentHandler: INExtension, INSendMessageIntentHandling, CLLocationManagerDelegate, UISceneDelegate
are ever called.
Is there any problem with CLLocation manager on intents? What would be a big problem as there is no way to share information with the main app!
Hello Apple Developer Community,
I’m working on integrating Siri into my React Native app using native iOS code and bridging to React Native. I’ve followed the necessary steps to set up Siri support, including:
Adding the Siri capability.
Adding Siri usage descriptions in Info.plist.
Using AppIntent and AppShortcutsProvider to define shortcuts.
However, I’m facing the following issues:
Siri Prompts for Confirmation
When a user says a phrase, Siri asks, "Turn on 'MyApp' shortcuts with Siri?" instead of directly recognizing the phrase. Is this expected behavior? If so, how can I reduce friction for users and make the experience more seamless?
Inconsistent Behavior for Existing Users
For users updating to a version with Siri support:
When the app is closed, Siri says, "MyApp hasn't added support for that with Siri."
When the app is open, Siri prompts, "Turn on shortcut for MyApp?" and rest all working fine
Why does Siri not recognize the shortcut when the app is closed, even though the shortcut is defined in AppShortcutsProvider? How can I ensure that Siri recognizes the shortcut regardless of whether the app is open or closed? Other than using AppIntent and AppShortcutsProvider should i try Donating shortcuts(will that helps for updated user case). Please help me on this
Platform and Version
iOS
Development Environment: Xcode 16.2.0, macOS 15.3
Run-time Configuration: iOS 18.3, 17.x
Description of Problem
We have started migrating some of the app’s core functionality over to App Intents.
Our first release of App Intent support focused on two settings a user can modify on their Bose products, Audio Modes and Immersive Audio, giving users the ability to modify these settings via Siri and shortcuts. The implementation uses two separate shortcuts for each setting type, with each shortcut supporting a single phrase for Siri each: “Change my Bose mode to ” and “Change my Bose immersive audio to ”. Each shortcut uses their own App Intent, and each App Intent has support for optionally providing both a product and a setting when performing the intent. Failing to provide a device, which happens when the intent is performed via Siri, simply auto selects a currently connected Bose product. Failing to provide a setting, like in cases where a user says “Change my Bose ” without providing a setting will simply have Siri confirm the setting the user wants to change before changing the setting. We are using AppEntity to identify a Bose product for both App Intents. Because the App Intent for the Audio Modes setting has a larger number of supported values (up to 15 maximum), we are also using AppEntity to identify these settings. We are using AppEnum to identify available settings for the Immersive Audio App Intent, as only 3 static values are supported.
Our original implementation of App Intent support had quite a few phrases supported for each shortcut. We had explicit support for direct synonyms of the verb “Change” in other phrases, supporting words like “Switch” and “Set”. We also had support for words that are like the word “Change”, but not directly related, like the word “Toggle” for instance. We also had support for phrases with or without the setting in each phrase. However, early on we had a lot of trouble with phrase detection with Siri. Siri had a hard time identifying what shortcut was being requested, as well as not being able to identify what settings the user was providing for the setting parameter of each App Intent. While researching potential fixes for this issue, we found a response to a thread in the Apple forums (https://developer.apple.com/forums/thread/759909) that seemed to indicate that Siri phrase recognition was very much an aggregate process. With the total number of phrases supported combined with the available settings for each phrase further compounding the total number of phrases Siri needs to learn to recognize for each shortcut. So, to hopefully improve Siri phrase detection, we added logic to limit the amount of Audio Mode settings supported based on what Audio Modes the user had setup on their Bose products. But, more importantly, we limited the number of explicit phrases supported for each shortcut to just a single phrase. In our testing, not only did this improve phrase recognition, but support for synonyms like “Set” or “Switch” seemed to implicitly still be recognized by Siri.
The issues we ran into with Siri phrase detection above has us a bit concerned about scaling App Intent support to other settings and features for our products in the future. Our app supports the ability to modify a large number of settings on their Bose products, with support constantly expanding to new products as they are released. Our roadmap for App Intent support was initially very ambitious, supporting much more than just the two settings mentioned above. But our initial experience with App Intents has us tapering our expectations a little bit as far as how much can be supported in total for App Intents.
One thing we also noticed is less than optimal display of default shortcuts in the Shortcuts app. The default shortcuts appeared like so, with shortcuts displayed based on available settings fro each shortcut:
However, we could not find a way to indicate to users that one particular section pertained specifically to the Audio Mode setting and the other to the Immersive Audio setting. The only information the user has to make this determination for themselves is the available settings (or shortcuts) for each. This may not be immediately clear to a new customer who might be using one of our products for the first time. This display of default shortcuts in the Shortcuts app has us wondering if our shortcuts implementation is what is intended as far as support for the Shortcuts app is concerned. We did survey default shortcuts displayed by other third-party applications and they mostly dealt with navigation with a single section containing default options clearly indicating where the user can navigate with a shortcut. We couldn’t find an example of an application supporting the ability to change different setting types, with each setting type having their own available values for each.
So, to summarize the questions we have concerning App Intent support:
What can we do with our App Intents and Shortcuts implementation to guarantee optimal performance with Siri?
What is an ideal number of phrases to support for each Shortcut.
What limitations should we be placing as far as the total number of available settings for each Shortcut.
Are there phrases that might work better than others for what we’re trying to achieve with App Intent support?
i.e. Is “Change my Bose mode” or “Change my Bose immersive audio” a good phrase to use for this kind of functionality? Or should we be using different verbs or wording?
Assuming optimal support of each Shortcut above. What is a reasonable expectation as far as how many different supported shortcuts we can scale to support at the same time.
One issue we ran into early on was Siri confusing one shortcut with the other and triggering the wrong App Intent at times. While this was ultimately resolved, this outcome seems much more likely the greater the number of individual shortcuts supported.
Are there any recommendations on how to display these App Intents to customers as far as default shortcuts in the Shortcuts app is concerned?
Is what we currently display for default shortcuts in the Shortcuts app what was initially intended for third party support for App Intents?
If what we are currently displaying is expected, would it be possible to support the ability to provide additional context to each section of default shortcuts displayed? We would like to indicate to the user that one set of shortcuts pertains to the Audio Modes settings, and the other to Immersive Audio. Something along the lines of a section header like some of the first-party apps use.
Are there any recommendations or tips for supporting App Intents, particularly phrases for Siri, in other languages?
I dont know if this is the appropriate forum for this.
Answers I've found on the web points me towards intentions, but somehow I couldnt make it work.
Im trying to activate siri on carplay to ask user for voice input then make a search.
Is this a custom intent capability or is there any other way.
I am building a widget with configurable options (dynamic option) where the options are pull from api (ultimately the options are return from a server, but during my development, the response is constructed on the fly from locally).
Right now, I am able to display the widget and able to pull out the widget configuration screen where I can choose my config option . I am constantly having an issue where the loading the available options when selected a particular option (e.g. Category) and display them on the UI. Sometime, when I tap on the option "Category" and the loading indicator keeps spinning for while before it can populate the list of topics (return from methods in NewsCategoryQuery struct via fetchCategoriesFromAPI ). Notice that I already made my fetchCategoriesFromAPI call to return the result on the fly and however the widget configuration UI stills take a very long time to display the result. Even worst, the loading (loading indicator keep spinning) sometime will just kill itself after a while and my guess there are some time threshold where the widget extension or app intent is allow to run, not sure on this?
My questions:
How can I improve the loading time to populate the dynamic options in widget configuration via App Intent
Here is my sample code for my current setup
struct NewsFeedConfigurationIntent: AppIntent, WidgetConfigurationIntent {
static let title: LocalizedStringResource = "Configure News Topic Options"
static let description = IntentDescription("Select a topic for your news.")
@Parameter(title: "Category", default: nil)
var category: NewsCategory?
}
struct NewsCategory: AppEntity, Identifiable {
let id: String
let code: String
let name: String
static let typeDisplayRepresentation: TypeDisplayRepresentation = "News Topic"
static let defaultQuery = NewsCategoryQuery()
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: LocalizedStringResource(stringLiteral: name))
}
}
struct NewsCategoryQuery: EntityQuery {
func entities(for identifiers: [NewsCategory.ID]) async throws -> [NewsCategory] {
let categories = fetchCategoriesFromAPI()
return categories.filter { identifiers.contains($0.id) }
}
func suggestedEntities() async throws -> [NewsCategory] {
fetchCategoriesFromAPI()
}
}
func fetchCategoriesFromAPI() -> [NewsCategory] {
let list = [
"TopicA",
"TopicB",
"TopicC",
.......
]
return list.map { item in
NewsCategory(id: item, code: item, name: item.capitalized)
}
}
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
WidgetKit
Intents
App Intents
After installing the latest version of Xcode (16.3, 16E140), I get many instances of this error when building my app: Error: Multiple parameters detected in phrase. A single phrase can only use a single parameter.
Here is an example of an App Shortcut that is causing this error:
AppShortcut(
intent: SelectModelIntent(),
phrases: [
"Select \(\.$model) in \(.applicationName)",
],
shortTitle: LocalizedStringResource("Select Model", comment: "Title for Shortcut"),
systemImageName: "rectangle.3.group"
)
If I replace the application name parameter with a hard-coded string, I get an error that says I need to have the application name parameter in each phrase. So is it not possible to have any other parameters in a phrase besides the application name? That seems unlikely to me.
I want to use MapKit with App Intents, but the map does not show up.(See attached image)
Can anyone help me solve this?
import SwiftUI
import MapKit
struct ContentView: View {
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 37.334_900,
longitude: -122.009_020),
latitudinalMeters: 750,
longitudinalMeters: 750
)
var body: some View {
VStack {
Map(coordinateRegion: $region).frame(width:300, height:300)
.disabled(true)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
import AppIntents
import SwiftUI
import MapKit
struct test20220727bAppIntentsExtension: AppIntent {
static var title: LocalizedStringResource = "test20220727bAppIntentsExtension"
func perform() async throws -> some IntentResult {
return .result(value: "aaa", view: ContentView())
}
}
struct testShortcuts:AppShortcutsProvider{
@available(iOS 16.0, *)
static var appShortcuts: [AppShortcut]{
AppShortcut(
intent: test20220727bAppIntentsExtension(),
phrases: ["test20220727bAppIntentsExtension" ]
)
}
}
Topic:
App & System Services
SubTopic:
Maps & Location
Tags:
App Intents
wwdc2022-10032
wwdc2022-10170
I have a chat/search functionality in my app, I want to integrate siri where user can say something "Hey siri! Ask myApp to get latest news" then I want to invoke my search functionality with "get latest news". I see iOS apps like chatGPT and youtube have already achieved this.
I am able to invoke the intent with static phrase which is expecting the parameter, user is able to provide the value when prompted after requestValueDialog. But it is a 2 step process for end user. I want to achieve in a single step.
struct CombinedSiriShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
return [
AppShortcut(
intent: ShowSpecificNewsArticleIntent(),
phrases: [
"Ask \(.applicationName) to run a query:",
],
shortTitle: "Specific News Article",
systemImageName: "doc.text.fill"
),
AppShortcut(
intent: TestQuery(),
phrases: [
"Ask \(.applicationName) to \(\.$query)",
],
shortTitle: "Test intent",
systemImageName: "doc.text.fill"
),
]
}
}
struct ShowSpecificNewsArticleIntent: AppIntent {
static var title: LocalizedStringResource = "Show Specific News Article"
static var description = IntentDescription(
"Provides details about a specific news article based on its title."
)
@Parameter(title: "Query")
var query: String
@MainActor
func perform() async throws -> some IntentResult & ProvidesDialog & ShowsSnippetView {
print("in show specific intent");
print(query);
return .result(dialog: "view more about: \(query)")
}
}
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
Siri and Voice
SiriKit
App Intents
I made a set of Siri Shortcuts in my app with the AppShortcutsProvider, and they each have a set of phrases.
I can activate the shortcuts via Siri phrases or Spotlight search on iOS 18+, but not on iOS -17.
I've checked the documentation and see that AppShortcutsProvider is supported from iOS 16+, so I don't understand why I can't view the shortcuts in Spotlight or activate them with Siri unless it's at least iOS 18.
Any thoughts?
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
Spotlight
Siri and Voice
Shortcuts
App Intents
Hello, experts!
I'm working on a VOIP application that handles audio calls and integrates with CallKit. The problem occurs when attempting to redial a previously made audio call from the system's call history. When I try to handle the NSUserActivity in the application(_:continue:restorationHandler:) method, it intercepts the INStartAudioCallIntent instead of the expected INStartCallIntent.
Background
Deprecation Warnings: I'm encountering deprecation warnings when using INStartAudioCallIntent and INStartVideoCallIntent:
'INStartAudioCallIntent' was deprecated in iOS 13.0: INStartAudioCallIntent is deprecated. Please adopt INStartCallIntent instead.
'INStartVideoCallIntent' was deprecated in iOS 13.0: INStartVideoCallIntent is deprecated. Please adopt INStartCallIntent instead.
As a result, I need to migrate to INStartCallIntent instead, but the issue is that when trying to redial a call from the system’s call history, INStartAudioCallIntent is still being triggered.
Working with Deprecated Intents: If I use INStartAudioCallIntent or INStartVideoCallIntent, everything works as expected, but I want to adopt INStartCallIntent to align with the current iOS recommendations.
Configuration:
CXProvider Configuration: The CXProvider is configured as follows:
let configuration = CXProviderConfiguration()
configuration.supportsVideo = true
configuration.maximumCallsPerCallGroup = 1
configuration.maximumCallGroups = 1
configuration.supportedHandleTypes = [.generic]
configuration.iconTemplateImageData = UIImage(asset: .callKitLogo)?.pngData()
let provider = CXProvider(configuration: configuration)
Outgoing Call Handle: When making an outgoing call, the CXHandle is created like this:
let handle = CXHandle(type: .generic, value: callId)
Info.plist Configuration: In the info.plist, the following key is defined:
<key>NSUserActivityTypes</key>
<array>
<string>INStartCallIntent</string>
</array>
Problem:
When trying to redial the audio call from the system's call history, the NSUserActivity received in the application(_:continue:restorationHandler:) method is an instance of INStartAudioCallIntent instead of INStartCallIntent. This happens even though INStartCallIntent is listed in NSUserActivityTypes in the info.plist and I want to migrate to the newer intent as recommended in iOS 13+.
Device:
iPhone 13 mini
iOS version 17.6.1
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
Foundation
CallKit
Intents
App Intents