App Intents

RSS for tag

Extend your app’s custom functionality to support system-level services, like Siri and the Shortcuts app.

Posts under App Intents tag

168 Posts

Post

Replies

Boosts

Views

Activity

Using App Intents in Live Activity to Pause a Timer
Hello, I am trying to test a concept of a timer stopwatch with Live Activities and integrating buttons like Pause/Resume. When the stopwatch starts, a new Live Activity is created. The stopwatch is managed by the ViewModel, which has functions like start(), pause(), resume(), reset(), and also startLiveActivity(), etc. It uses @AppStorage to store keys like stopWatchModeRaw values, startTimeInterval, etc. The Live Activity state is stored here in the view model using: private var currentActivity: Activity? = nil The Live Activity is started using: private func startActivity() async { guard currentActivity == nil, Activity<StopwatchAttributes>.activities.isEmpty else { if currentActivity == nil { findAndAssignExistingActivity() await updateActivity() } return } let attributes = StopwatchAttributes() let state = StopwatchAttributes.ContentState( .... pass in the content state variables .... ) let content = ActivityContent(state: state, staleDate: nil) do { let activity = try Activity<StopwatchAttributes>.request( attributes: attributes, content: content, pushType: nil ) // Store the activity instance self.currentActivity = activity } catch { print("Error requesting Live Activity: \(error.localizedDescription)") } } and FindAndAssignExistingAcivity does: private func findAndAssignExistingActivity() { if let existingActivity = findActivity(), existingActivity.activityState == .active || existingActivity.activityState == .stale { print("Found existing activity on launch: \(existingActivity.id)") self.currentActivity = existingActivity } else { print("No existing activity found on launch.") self.currentActivity = nil } } UpdateActivity if the activity exists with a guard statement, and then update the activity. This is also used when the user taps Pause in the Stopwatch. The main issue I am facing is with the PauseIntent, it can't find the Live Activity and will always exit at that guard statement. struct PauseIntent: AppIntent { static var title: LocalizedStringResource = "Pause Stopwatch" func perform() async throws -> some IntentResult { guard let defaults = UserDefaults(suiteName: appGroupID) else { return .result() // Simple failure } let currentModeRaw = defaults.integer(forKey: "stopwatchModeRawValue") let currentMode = StopwatchMode(rawValue: currentModeRaw) ?? .reset let startTimeInterval = defaults.double(forKey: "startTimeInterval") // TimeInterval when current running segment started let accumulatedTime = defaults.double(forKey: "accumulatedTime") guard let activity = Activity<StopwatchAttributes>.activities.first else { Self.logger.error("PauseIntent EXIT: No Live Activity found to update. (Activity<StopwatchAttributes>.activities is empty)") return .result() // EXITING HERE, No Live Activity Found, there was nothing found to update... -> It always exits here } followed by rest of the code to update the state of the live activity, but it never executes because the activity = Activity.activities.first always returns false. What seems to be the issue? 1 .Is the method wrong to check for the live activity before attempting to Pause? 2. Can the Live Activity actually Pause the Stopwatch Timer in the main App since the Live Activity is actually a Widget Extension and not the App itself, so it cannot see the data directly?
1
0
128
May ’25
Siri Intent - Car Commands
Hi Community, I'm new on Siri intents and I'm trying to introduce into my App a Siri Intent for Car Commands. The objective is to list into the Apple Maps the Car list of my App. Currently I've created my own target with its corresponding IntentHandlings, but in the .intentdefinition file of my App, I'm not able to find the List Car Intent. https://developer.apple.com/documentation/sirikit/car-commands Do I need some auth? Also I share my info.plist from the IntentExtension. Thank you very much, David.
0
0
204
May ’25
App Shortcuts Preview: No Matching Intent?
Hi! In neither Xcode 16.2 beta 3 nor Xcode 16.2 I am able to get App Shortcuts Preview to recognise my Shortcuts. In either supported language I always get "No Matching Intent" as the result. Flexible matching is enabled, minimum deployment target is iOS 18. The Shortcut phrases do work in the simulator and on device. Is this a known issue or am I missing something?
8
1
703
Apr ’25
Use Siri to control parts of my CarPlay app
I am building a CarPlay navigation app and I would like it to be as hands free as possible. I need a better understanding of how Siri can work with CarPlay and if the direction I need to go is using Intents or App Shortcuts. My goal is to be able to have the user speak to Siri and do things like "open settings" or "zoom in map" and then call a func in my app to do what the user is asking. Does CarPlay support this? Do I need to use App Intents or App Shortcuts or something else?
2
0
182
Apr ’25
Help getting elements from SwiftData in AppIntent for widget
Hello, I am trying to get the elements from my SwiftData databse in the configuration for my widget. The SwiftData model is the following one: @Model class CountdownEvent { @Attribute(.unique) var id: UUID var title: String var date: Date @Attribute(.externalStorage) var image: Data init(id: UUID, title: String, date: Date, image: Data) { self.id = id self.title = title self.date = date self.image = image } } And, so far, I have tried the following thing: AppIntent.swift struct ConfigurationAppIntent: WidgetConfigurationIntent { static var title: LocalizedStringResource { "Configuration" } static var description: IntentDescription { "This is an example widget." } // An example configurable parameter. @Parameter(title: "Countdown") var countdown: CountdownEntity? } Countdowns.swift, this is the file with the widget view struct Provider: AppIntentTimelineProvider { func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: Date(), configuration: ConfigurationAppIntent()) } func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry { SimpleEntry(date: Date(), configuration: configuration) } func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> { var entries: [SimpleEntry] = [] // Generate a timeline consisting of five entries an hour apart, starting from the current date. let currentDate = Date() for hourOffset in 0 ..< 5 { let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! let entry = SimpleEntry(date: entryDate, configuration: configuration) entries.append(entry) } return Timeline(entries: entries, policy: .atEnd) } // func relevances() async -> WidgetRelevances<ConfigurationAppIntent> { // // Generate a list containing the contexts this widget is relevant in. // } } struct SimpleEntry: TimelineEntry { let date: Date let configuration: ConfigurationAppIntent } struct CountdownsEntryView : View { var entry: Provider.Entry var body: some View { VStack { Text("Time:") Text(entry.date, style: .time) Text("Title:") Text(entry.configuration.countdown?.title ?? "Default") } } } struct Countdowns: Widget { let kind: String = "Countdowns" var body: some WidgetConfiguration { AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in CountdownsEntryView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) } } } CountdownEntity.swift, the file for the AppEntity and EntityQuery structs struct CountdownEntity: AppEntity, Identifiable { var id: UUID var title: String var date: Date var image: Data var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(title)") } static var defaultQuery = CountdownQuery() static var typeDisplayRepresentation: TypeDisplayRepresentation = "Countdown" init(id: UUID, title: String, date: Date, image: Data) { self.id = id self.title = title self.date = date self.image = image } init(id: UUID, title: String, date: Date) { self.id = id self.title = title self.date = date self.image = Data() } init(countdown: CountdownEvent) { self.id = countdown.id self.title = countdown.title self.date = countdown.date self.image = countdown.image } } struct CountdownQuery: EntityQuery { typealias Entity = CountdownEntity static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Countdown Event") static var defaultQuery = CountdownQuery() @Environment(\.modelContext) private var modelContext // Warning here: Stored property '_modelContext' of 'Sendable'-conforming struct 'CountdownQuery' has non-sendable type 'Environment<ModelContext>'; this is an error in the Swift 6 language mode func entities(for identifiers: [UUID]) async throws -> [CountdownEntity] { let countdownEvents = getAllEvents(modelContext: modelContext) return countdownEvents.map { event in return CountdownEntity(id: event.id, title: event.title, date: event.date, image: event.image) } } func suggestedEntities() async throws -> [CountdownEntity] { // Return some suggested entities or an empty array return [] } } CountdownsManager.swift, this one just has the function that gets the array of countdowns func getAllEvents(modelContext: ModelContext) -> [CountdownEvent] { let descriptor = FetchDescriptor<CountdownEvent>() do { let allEvents = try modelContext.fetch(descriptor) return allEvents } catch { print("Error fetching events: \(error)") return [] } } I have installed it in my phone and when I try to edit the widget, it doesn't show me any of the elements I have created in the app, just a loading dropdown for half a second: What am I missing here?
0
0
150
Apr ’25
Disambiguation for .system.search AppIntent
I'd like to display a list of items to disambiguate for a fulltext search intent. Using the Apple AppIntentsSampleApp, I added TrailSearch.swift: import AppIntents @AssistantIntent(schema: .system.search) struct TrailSearch: AppIntent { static let title: LocalizedStringResource = "Search Trail" static let description = IntentDescription("Search trail by name.", categoryName: "Discover", resultValueName: "Trail") @Parameter(title: "Trail") var criteria: StringSearchCriteria func perform() async throws -> some IntentResult & ReturnsValue<TrailEntity> { if criteria.term.isEmpty { throw $criteria.needsValueError(IntentDialog("need value")) } let trails = TrailDataManager.shared.trails { trail in trail.name.contains(criteria.term) } if trails.count > 1 { throw $criteria.needsDisambiguationError(among: trails.map { StringSearchCriteria(term: $0.name) }) } else if let firstTrail = trails.first { return .result(value: TrailEntity(trail: firstTrail)) } throw $criteria.needsValueError(IntentDialog("Nothing found")) } } Now when I type "trail" which matches several trails and thus lets us enter the disambiguation code path, the Shortcut app just displays the dialog title but no disambiguation items to pick from. Is this by design or a bug? (filed as FB17412220)
0
0
103
Apr ’25
Siri Shortcuts of Siri Intent to Voice Control Parts of App
I am new to the idea of Siri Shortcuts and App Intents. What I want to do is use Siri to run a function in my app. Such as saying to Siri Zoom in map and that will then call a function in my app where I can zoom in the map. Similarly, I could say Zoom out map and it would call a function to zoom out my map. I do not need to share any sort of shortcut with the Shortcuts app. Can someone please point me in the right direction for what type of intents I need to use for this?
0
0
145
Apr ’25
Parameter recognition on AppShortcuts invocation not consistent
While playing around with AppShortcuts I've been encountering some problems around getting the invocation phrase detected and/or the parameter get recognized after invocation phrase via Siri. I've found some solutions or explanations here in other posts (Siri not recognizing the parameter in the phrase & Inform iOS about AppShortcutsProvider), but I still have one issue and it's about consistency. For context, I've defined the parameter to be an AppEntity with it's respective query conforming to the EntityStringQuery Protocol in order to be able to fetch entities with the string given by Siri struct AnIntent: AppIntent { // other parts hidden for clarity @Parameter var entity: ModelEntity } For an invocation phrase akin to "Do something with in ", if the user uses the phrase with a entity previously donated via suggestedEntities() the AppShortcut get executed without problems. If the user uses a phrase with no parameter, like "do something with ", if the user gets asked to input the missing parameter and inputs one, it may or may not get recognized and be asked to input a parameter again, like in a loop. This happens even if the parameter given is one that was donated. I've found that when this happens the entities(matching string: String) function in the EntityQuery doesn't get called. The input can be of one word or sometimes two and it will not be called. So in other words entities(matching string: String) does not get called on every user parameter input Is this behavior correct? Do parameters have some restrictions on length or anything? Does Siri shows the user suggested entities when asked for entity input? It doesn't on my end. Additional question related to AppShortcuts: On AppShortcut definition, where the summary inside the parameter presentation is used? I see that it was defined in the AppIntentsSampleApp for the GetTrailInfo Intent but didn't find where it was used
0
0
99
Apr ’25
Dynamic parameters in shortcuts
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?
5
0
354
Apr ’25
Duration type parameter in AppIntent
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
3
0
101
Apr ’25
What is the correct syntax to continue in app for custom intent?
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?
1
0
133
Apr ’25
Can NWBrowser be used in an AppIntent extension? NoAuth
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.
1
0
111
Apr ’25
Improving references to localized strings in App Intents
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.
0
0
132
Apr ’25
Interactive Live Activity Bug in iOS 18 - perform not called
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?
4
2
1.4k
Apr ’25
[Widget] ChronoKit.InteractiveWidgetActionRunner.Errors.runnerClientError `There is no metadata for `
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.
1
2
182
Apr ’25
Launch App with Siri on a locked device
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" ) } }
1
0
116
Apr ’25
AppIntentTimelineProvider "func timeline(for" is called twice after a widget button triggers an AppIntent Perform
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
3
0
793
Apr ’25
CLLocationManagerDelegate not working on Siri Intents
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!
2
0
115
Apr ’25