After watching the What's new in App Intents session I'm attempting to create an intent conforming to URLRepresentableIntent. The video states that so long as my AppEntity conforms to URLRepresentableEntity I should not have to provide a perform method . My application will be launched automatically and passed the appropriate URL.
This seems to work in that my application is launched and is passed a URL, but the URL is in the form: FeatureEntity/{id}.
Am I missing something, or is there a trick that enables it to pass along the URL specified in the AppEntity itself?
struct MyExampleIntent: OpenIntent, URLRepresentableIntent {
static let title: LocalizedStringResource = "Open Feature"
static var parameterSummary: some ParameterSummary {
Summary("Open \(\.$target)")
}
@Parameter(title: "My feature", description: "The feature to open.")
var target: FeatureEntity
}
struct FeatureEntity: AppEntity {
// ...
}
extension FeatureEntity: URLRepresentableEntity {
static var urlRepresentation: URLRepresentation {
"https://myurl.com/\(.id)"
}
}
Intents
RSS for tagShare intents from within an app to drive system intelligence and show the app's actions in the Shortcuts app.
Posts under Intents tag
74 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am trying to implement URLRepresentableEntity on my AppEntity
I am following along with the WWDC video here
All compiles fine when I use the ID as in the video:
extension SceneEntity: URLRepresentableEntity {
static var urlRepresentation: URLRepresentation {
"https://example.com/scene/\(.id)"
}
}
but my URLs need to use a different property on the Entity. The WWDC video clearly states: "Notice that I'm using the entity’s identifier as an interpolated value. You can use an entity’s ID or any of its properties with the @Property attribute as interpolations in the URL string."
So I annotated my entity with the @Property attribute and expected that to work but it doesn't compile.
struct SceneEntity: AppEntity {
let id: UUID
@Property(title: "Slug") var slug: String
}
extension SceneEntity: URLRepresentableEntity {
static var urlRepresentation: URLRepresentation {
"https://example.com/scene/\(.slug)"
}
}
Type 'EntityURLRepresentation.StringInterpolation.Token' has no member 'slug'
How can I use this API with a property that is not the ID?
I'm building out a live activity that has a button which is meant to update the content state of the Live Activity. It calls a LiveActivityIntent that runs in the app process.
The push server starts my live activity and the buttons work just fine. I pass the push token back to the server for further updates and when the next update is pushed by the server the buttons no longer work. With the debugger I'm able to verify the app intent code runs and passes the updated state to the activity. However the activity never updates or re-renders. There are no logs in Xcode or Console.app that indicates what the issue could be or that the update is ignored.
I have also tried adding the frequent updates key to my plist with no change.
I'm updating the live activity in the LiveActivityIntent like this:
public func perform() async throws -> some IntentResult {
let activities = Activity<WidgetExtensionAttributes>.activities
for activity in activities {
let currentState = activity.content.state
let currentIndex = currentState.pageIndex ?? 0
let maxIndex = max(0, currentState.items.count - 1)
let newIndex: Int
if forward {
newIndex = min(currentIndex + 1, maxIndex)
} else {
newIndex = max(currentIndex - 1, 0)
}
var newState = currentState
newState.pageIndex = newIndex
await activity.update(
ActivityContent(
state: newState,
staleDate: nil
),
alertConfiguration: nil,
timestamp: Date()
)
}
return .result()
}
To sum up:
Push to start -> tap button on activity -> All good!
Push to start -> push update -> tap button -> No good...
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
APNS
Intents
App Intents
ActivityKit
Currently, we are developing an all-in-one DualSense utility for macOS. We are exploring how to integrate shortcuts into our app. Our vision is to have the user use the native Shortcuts app to choose the controller buttons that should trigger the shortcut action, such as opening Steam, turning on audio haptics, and more.
As we explore this approach, we want to see whether we need to build the UI in our app to set the triggers or can we do this inside of Shortcuts? Can button presses recorded by our app trigger shortcuts? Can those button inputs be customized inside of Shortcuts or should we develop it into our app? And if we have it in our app, can our app see, select, and trigger shortcuts?
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
macOS
Shortcuts
Intents
App Intents
The following code works perfectly fine in iOS 17, where I can retrieve the desired dependency value through @IntentParameterDependency as expected. However, in iOS 18, addTransaction always returns nil.
struct CategoryEntityQuery: EntityStringQuery {
@Dependency
private var persistentController: PersistentController
@IntentParameterDependency<AddTransactionIntent>(
\.$categoryType
)
var addTransaction
func entities(matching string: String) async throws -> [CategoryEnitity] {
guard let addTransaction else {
return []
}
// ...
}
func entities(for identifiers: [CategoryEnitity.ID]) async throws -> [CategoryEnitity] {
guard let addTransaction else {
return []
}
// ...
}
func suggestedEntities() async throws -> [CategoryEnitity] {
guard let addTransaction else {
return []
}
// ...
}
}
Has anyone else encountered the same issue? Any insights or potential workarounds would be greatly appreciated.
iOS: 18.0 (22A3354)
Xcode 16.0 (16A242d)
Hello everybody!
Does anybody know how to set default values for string array intent field provided dynamically? I want to have preset array field values just after widget added
I have a simple accessory widget with circular and rectangular representation (the first one is for 1 currency value and the second one is for 3 values).
I created CurrencyWidgets.intentdefinition and added AccessoryCurrency custom intent. Here I added string parameter field currencyCode. For this parameter I set the following options:
Supports Multiple Values
Fixed Size (AccessoryCircular = 1, AccessoryRectangular = 3)
User can edit value in Shortcuts
Options are provided dynamically
Then I created CurrencyTypeIntent extension and added IntentHandler for my custom intent AccessoryCurrency. The code is below
class IntentHandler: INExtension, AccessoryCurrencyIntentHandling {
override func handler(for intent: INIntent) -> Any { self }
func provideCurrencyCodeOptionsCollection(for intent: AccessoryCurrencyIntent) async throws -> INObjectCollection<NSString> {
return INObjectCollection(items: [NSString("USD"), NSString("EUR"), NSString("RUB"), NSString("CNY")])
}
func defaultCurrencyCode(for intent: AccessoryCurrencyIntent) -> [String]? {
return ["USD", "EUR", "RUB"]
}
}
The problem is in func defaultCurrencyCode(...): when I return something except nil (for example ["USD"] or ["USD", "EUR", "RUB"]) then I got a broken widget. It hangs in a placeholder state in lock screen and at add widget UI (see the image below).
Otherwise when I return nil then my widget works fine. But when I try to customise widget then I don't have default values for my currencyCode field, only Chose placeholders.
At the same time everything works fine for the single string parameter (without "Supports Multiple Values"). Does anybody know how to make default parameters work for array (multiple) field?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
WidgetKit
Intents
App Intents
Overview
I have a custom type Statistics that has 3 properties inside it
I am trying to return this as part of the AppIntent's perforrm method
struct Statistics {
var countA: Int
var countB: Int
var countC: Int
}
I would like to implement the AppIntent to return Statistics as follows:
func perform() async throws -> some IntentResult & ReturnsValue<Statistics> {
...
...
}
Problem
It doesn't make much sense to make Statistics as an AppEntity as this is only computed as a result.
Statistics doesn't exist as a persisted entity in the app.
Questions
How can I implement Statistics?
Does it have to be AppEntity (I am trying to avoid this)? (defaultQuery would never be used.)
What is the correct way tackle this?
Hi,
I have created an AppIntent in which there is a parameter called price, I have set the default value as 0.
@Parameter(title: "Price", default: 0)
var price: Int
Problem
When the shortcut is run this parameter is skipped
Aim
I still want to price to be asked however it needs to be pre-filled with 0
Question
What should I do that the shortcut can still ask the price but be pre-filled with 0?
使用APPIntent 的AppShortcutsProvider方式,最多只能添加10个AppShortcut,超过10个,代码编译就会报错
struct MeditationShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: StartMeditationIntent(),
phrases: [
"Start a (.applicationName)",
"Begin (.applicationName)",
"Meditate with (.applicationName)",
"Start a (.$session) session with (.applicationName)",
"Begin a (.$session) session with (.applicationName)",
"Meditate on (.$session) with (.applicationName)"
]
)
}
}
如何能做到像特斯拉APP一样
Hi everyone,
I’m currently experimenting with App Intents and I’m trying to customize the section titles that appear at the top of groups of intents inside the Shortcuts app UI.
For example, in the Phone shortcut, there are built-in sections such as “Call Favorite Contacts” and “Call Recent Contacts” (see screenshot attached).
Apple’s own system apps such as Phone, Notes, and FaceTime seem to have fully custom section headers inside Shortcuts with icon.
My question is:
👉 Is there an API available that allows third-party apps to define these titles (or sections) programmatically?
I went through the AppIntents and Shortcuts documentation but couldn’t find anything.
From what I can tell, this might be private / Apple-only behavior, but I’d be happy to know if anybody has found a supported solution or a recommended alternative.
Has anyone dealt with this before?
Thanks!
Mickaël 🇫🇷
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
Siri and Voice
Shortcuts
Intents
App Intents
I am implementing AppIntent into my application as follows:
// MARK: - SceneDelegate
var window: UIWindow?
private var observer: NSObjectProtocol?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
// Setup window
window = UIWindow(windowScene: windowScene)
let viewController = ViewController()
window?.rootViewController = viewController
window?.makeKeyAndVisible()
setupUserDefaultsObserver()
checkShortcutLaunch()
}
private func setupUserDefaultsObserver() {
// use NotificationCenter to receive notifications.
NotificationCenter.default.addObserver(
forName: NSNotification.Name("ShortcutTriggered"),
object: nil,
queue: .main
) { notification in
if let userInfo = notification.userInfo,
let appName = userInfo["appName"] as? String {
print("📱 Notification received - app is launched: \(appName)")
}
}
}
private func checkShortcutLaunch() {
if let appName = UserDefaults.standard.string(forKey: "shortcutAppName") {
print("🚀 App is opened from a Shortcut with the app name: \(appName)")
}
}
func sceneDidDisconnect(_ scene: UIScene) {
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
}
}
// MARK: - App Intent
struct StartAppIntent: AppIntent {
static var title: LocalizedStringResource = "Start App"
static var description = IntentDescription("Launch the application with the command")
static var openAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some IntentResult {
UserDefaults.standard.set("appName", forKey: "shortcutAppName")
UserDefaults.standard.set(Date(), forKey: "shortcutTimestamp")
return .result()
}
}
// MARK: - App Shortcuts Provider
struct AppShortcutsProvider: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: StartAppIntent(),
phrases: [
"let start \(.applicationName)",
],
shortTitle: "Start App",
systemImageName: "play.circle.fill"
)
}
}
the app works fine when starting with shortcut. but when starting with siri it seems like the log is not printed out, i tried adding a code that shows a dialog when receiving a notification from userdefault but it still shows the dialog, it seems like the problem here is when starting with siri there is a problem with printing the log.
I tried sleep 0.5s in the perform function and the log was printed out normally
try? await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds
I have consulted some topics and they said that when using Siri, Intent is running completely separately and only returns the result to Siri, never entering the Main App. But when set openAppWhenRun to true, it must enter the main app, right? Is there any way to find the cause and completely fix this problem?
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
SiriKit
Intents
App Intents
OSLog
I've been implemented App Shortcuts into my apps which are localized for a variety of languages.
The WWDC23 "Spotlight your app with App Shortcuts" has been extremely helpful in resolving my localized trigger phrases issue, but before I continue filling out all of the trigger phrases for my application I am concerned about a limitation that was mention in the video and need some additional information about it.
The limitations noted in the video at minute mark 21:26 states that:
Maximum 10 App Shortcuts (OK)
Maximum 1000 trigger phrases...
If I have 1 app and 10 shortcuts, and each shortcut only uses (.applicationName), this means I get to have 100 trigger phrases for each shortcut (for the sake of the discussion).
What I'm unsure about is when I begin providing localization do the localized triggered phrases count toward the trigger phrase limit? Essentially, for every language I support do I have to drop 1/2 of all of my trigger phrases to stay under the limit?
At the moment, my app is supporting 40 languages and I would like to know how localization affects the trigger phrase limit.
Thank you!
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
Shortcuts
Intents
App Intents
I donate INPlayMediaIntent to systerm(donate success), but not show in control center
My code is as follows
let mediaItems = mediaItems.map { $0.inMediaItem }
let intent = if #available(iOS 13.0, *) {
INPlayMediaIntent(mediaItems: mediaItems,
mediaContainer: nil,
playShuffled: false,
playbackRepeatMode: .none,
resumePlayback: true,
playbackQueueLocation: .now,
playbackSpeed: nil,
mediaSearch: nil)
} else {
INPlayMediaIntent(mediaItems: mediaItems,
mediaContainer: nil,
playShuffled: false,
playbackRepeatMode: .none,
resumePlayback: true)
}
intent.suggestedInvocationPhrase = "播放音乐"
let interaction = INInteraction(intent: intent, response: nil)
interaction.donate { error in
if let error = error {
print("Intent 捐赠失败: \(error.localizedDescription)")
} else {
print("Intent 捐赠成功 ✅")
}
}
Hello,
I’d like to ask about best practices for handling interactive snippet intents when working with the user’s location.
My use case is:
1. Get the user’s location
2. Fetch nearby data
3. Display it
My current flow is: try to show the snippet view in "loading" state while waiting for Core Location Manager, then fetch data and reload() the view.
BUT I’m running into an issue where I sometimes receive Core Location error 1 (not authorized), even though the main app has “While In Use” authorization.
It seems that in some cases, especially when the app has been force-closed, App Intents are unable to start location updates, even though I’m using supportedModes = .foreground(.dynamic).
Any guidance would be appreciated.
Cheers,
Ondrej
Topic:
App & System Services
SubTopic:
Maps & Location
Tags:
Core Location
Maps and Location
Intents
App Intents
App intent has a perform method that is async and can throw an error, but I can't find a way to actually await the result and catch the error if needed.
If I convert this working but non-waiting, non-catching code:
Button("Go", intent: MyIntent())
to this (so I can control awaiting and error handling):
Button("Go") {
Task {
do {
try await MyIntent().perform() // 👈
} catch {
print(error)
}
}
}
It crashes:
AppDependency with key "foo" of type Bar.Type was not initialized prior to access. Dependency values can only be accessed inside of the intent perform flow and within types conforming to _SupportsAppDependencies unless the value of the dependency is manually set prior to access.
Although it is invalid since the first version is working like a charm and dependencies are registered in the @main App init method and it is in the perform flow.
So how can we await the result of the AppIntent and handle the errors if needed in the app? Should I re-invent the Dependency mechanism?
I've created a Snippet for my iOS app which I want to be able to run from the LockScreen via a Shortcuts widget.
All works fine except when I run the shortcut and the App Snippet appears, it doesn't always render the SwiftUI view in the same way.
Sometimes the width boundaries are respected and sometimes not.
I've tested this on iOS 26.1 and iOS 26.2 beta 3
I think this is a bug but it would be great if anyone could see what I might be doing wrong if it's not.
Incase it is a bug I've filed a feedback (FB21076429) and I've created a stripped down sample project showing the issue and added screenshots showing the issue.
Basic code to reproduce issue:
// Intent.swift
// SnippetBug
import AppIntents
import Foundation
import SwiftUI
struct SnippetEntryIntent: AppIntent {
static let title: LocalizedStringResource = "Open Snippet"
static let description = IntentDescription("Shows a snippet.")
// Don’t open the app – stay in the snippet surface.
static let openAppWhenRun: Bool = false
func perform() async throws -> some ShowsSnippetIntent {
.result(snippetIntent: TestSnippetIntent())
}
}
struct TestSnippetIntent: SnippetIntent {
static let title: LocalizedStringResource = "Snippet Intent"
static let description = IntentDescription("Action from snippet.")
@MainActor
func perform() async throws -> some IntentResult & ShowsSnippetView {
.result(view: SnippetView(model: SnippetModel.shared))
}
}
@MainActor
final class SnippetModel {
static let shared = SnippetModel()
private init() {
}
}
struct SnippetView: View {
let model: SnippetModel
var body: some View {
HStack {
Text("Test Snippet with information")
Spacer()
Image(systemName: "heart")
}.font(.headline)
}
}
struct Shortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: SnippetEntryIntent(),
phrases: [
"Snippet for \(.applicationName)",
"Test Snippet \(.applicationName)"
],
shortTitle: "Snippet",
systemImageName: "barcode"
)
}
}
You also need these lines in your main App entry point:
import AppIntents
@main
struct SnippetBugApp: App {
init() {
let model = SnippetModel.shared
AppDependencyManager.shared.add(dependency: model)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
This is correct
This is incorrect
Hi!
I have an AppShortcutsProvider that has been marked @available(iOS 17.0, *), because all Intents used within it are only available in iOS 17. So the static var appShortcuts should only be accessible in iOS 17, obviously.
Now this code has been released and works fine for iOS 17 users. But I just noticed that around 150 iOS 16 users have crashed in the static var appShortcuts, or more specifically, the defaultQuery of one of the Intents. This should not be possible, as neither the AppShortcutsProvider, nor the Intent is exposed to iOS 16, they are marked as @available(iOS 17.0, *). Any idea why this could happen?
Here is the crash log:
Crashed: com.apple.root.user-initiated-qos.cooperative
0 libswiftCore.dylib 0x3e178c swift::ResolveAsSymbolicReference::operator()(swift::Demangle::__runtime::SymbolicReferenceKind, swift::Demangle::__runtime::Directness, int, void const*)
1 libswiftCore.dylib 0x40bec4 swift::Demangle::__runtime::Demangler::demangleSymbolicReference(unsigned char)
2 libswiftCore.dylib 0x408254 swift::Demangle::__runtime::Demangler::demangleType(__swift::__runtime::llvm::StringRef, std::__1::function<swift::Demangle::__runtime::Node* (swift::Demangle::__runtime::SymbolicReferenceKind, swift::Demangle::__runtime::Directness, int, void const*)>)
3 libswiftCore.dylib 0x3e9680 swift_getTypeByMangledNameImpl(swift::MetadataRequest, __swift::__runtime::llvm::StringRef, void const* const*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>)
4 libswiftCore.dylib 0x3e4d9c swift_getTypeByMangledName
5 libswiftCore.dylib 0x3e50ac swift_getTypeByMangledNameInContext
6 MyApp 0x3f6b8c __swift_instantiateConcreteTypeFromMangledName (<compiler-generated>)
7 MyApp 0x640e3c one-time initialization function for defaultQuery + 146 (IntentAction.swift:146)
8 libdispatch.dylib 0x3eac _dispatch_client_callout
9 libdispatch.dylib 0x56ec _dispatch_once_callout
10 MyApp 0x64109c protocol witness for static AppEntity.defaultQuery.getter in conformance IntentAction + 124 (IntentAction.swift:124)
11 AppIntents 0x15c760 _swift_stdlib_malloc_size
12 AppIntents 0x19dfd4 __swift_destroy_boxed_opaque_existential_1Tm
13 MyApp 0x52dadc specialized ActionIntent.init(action:) + 41 (ActionIntent.swift:41)
14 MyApp 0x52df80 specialized static MyShortcuts.appShortcuts.getter + 17 (MyShortcuts.swift:17)
We implemented AppIntents using EnumerableEntityQuery and @Dependency and we are receiving these crash reports:
AppIntents/AppDependencyManager.swift:120: Fatal error: AppDependency of type MyDependency.Type was not initialized prior to access. Dependency values can only be accessed inside of the intent perform flow and within types conforming to _SupportsAppDependencies unless the value of the dependency is manually set prior to access.
I can't post the stack because of the Developer Forums sensitive language filter :( but basically it's just a call to suggestedEntities of MyEntityQuery that calls the dependency getter and then it crashes.
My understanding was that when using @Dependency, the execution of the intent, or query of suggestedEntities in this case, would be delayed by the AppIntents framework until the dependency was added to the AppDependencyManager by me. At least that's what's happening in my tests. But in prod I'm having these crashes which I haven't been able to reproduce in dev yet.
Does anyone know if this is a bug or how can this be fixed? As a workaround, I can avoid using @Dependency and AppDependencyManager completely and make sure that all operations are async and delay the execution myself until the dependency is set. But I'd like to know if there's a better solution.
Thanks!
import AppIntents
struct MGIntents: AppIntent {
static var title = LocalizedStringResource("open app")
static var openAppWhenRun: Bool = true
func perform() async throws -> some IntentResult & ProvidesDialog {
return .result(dialog: "app open")
}
}
struct AppItentsShortcuts:AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(intent: MGIntents(),
phrases: ["\(.applicationName) Open app"],
shortTitle: "Open app",
systemImageName: "fan.desk.fill")
}
}
when use ,error more error。
when i delet openAppWhenRun ,is ok。why?
how I can do it? thank you!
import AppIntents
struct AddTodoIntent: AppIntent {
static var title: LocalizedStringResource = "Add Todo"
static var openAppWhenRun: Bool = true
func perform() async throws -> some IntentResult & ProvidesDialog {
.result(dialog: "New todo added successfully.")
}
}
struct ViewTodosIntent:AppIntent {
static var title: LocalizedStringResource = "View Todos"
func perform() async throws -> some IntentResult & ProvidesDialog {
.result(dialog: "Here are your todos...")
}
}
struct TodoAppShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: AddTodoIntent(),
phrases: ["\(.applicationName) Add a new todo"],
shortTitle: "New Todo",
systemImageName: "plus.circle"
)
AppShortcut(
intent: ViewTodosIntent(),
phrases: ["\(.applicationName) Show my todoso"],
shortTitle: "Show todos",
systemImageName: "plus.app"
)
}
}
when we used, it wrong
How did i can do it success?