Post

Replies

Boosts

Views

Activity

Reply to AppIntent perform method not called.
I created a simple TestWidget in my main app When I use the configurable widget (i.e. TestWidgetConfigurable) only the placeholder API gets called on TestEntryProvider and the widget shows a placeholder When I use the statically configured widget (i.e. TestWidget) then my timeline api gets called on TestEntryProvider. However when I tap the button in TestWidgetButtonView the perform button in TestIntent never gets called but the widget does refresh / reload the timeline. import AppIntents import WidgetKit import SwiftUI @available(iOS 17.0.0, *) struct TestWidgetConfigurationIntent: WidgetConfigurationIntent { static var title: LocalizedStringResource { "Alexa Test Widget" } static var description: IntentDescription { "Try to get intents working" } } public struct TestEntry: TimelineEntry { public let date: Date public init(date: Date = .now) { self.date = date } } @available(iOS 17.0.0, *) struct TestEntryProvider: AppIntentTimelineProvider, TimelineProvider { typealias Entry = TestEntry typealias Intent = TestWidgetConfigurationIntent func placeholder(in context: Context) -> TestEntry { TestEntry() } func snapshot(in context: Context) async -> TestEntry { TestEntry() } func snapshot(for configuration: TestWidgetConfigurationIntent, in context: Context) async -> TestEntry { await snapshot(in: context) } func timeline(in context: Context) -> Timeline<TestEntry> { let currentDate = Date.now let nextRefresh = Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)! let entry = TestEntry() let entries: [TestEntry] = [entry] let timeline = Timeline(entries: entries, policy: .after(nextRefresh)) return timeline } func timeline(for configuration: TestWidgetConfigurationIntent, in context: Context) async -> Timeline<TestEntry> { timeline(in: context) } func getSnapshot(in context: Context, completion: @escaping @Sendable (TestEntry) -> Void) { completion(TestEntry()) } func getTimeline(in context: Context, completion: @escaping @Sendable (Timeline<TestEntry>) -> Void) { completion(timeline(in: context)) } } @available(iOS 17.0.0, *) public struct TestWidget: Widget { static let widgetKind = "TestWidget" let kind: String = Self.widgetKind public init() {} public var body: some WidgetConfiguration { StaticConfiguration( kind: kind, provider: TestEntryProvider() ) { entry in TestWidgetFamilyView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) } .configurationDisplayName("Test Widget") .description("Test widget to try to get intents working") .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) } } @available(iOS 17.0.0, *) public struct TestWidgetConfigurable: Widget { // Note: This is the same as AlexaSmartHomeWidgetConfigurable.widgetKind static let widgetKind = "TestWidget" let kind: String = Self.widgetKind public init() {} public var body: some WidgetConfiguration { AppIntentConfiguration( kind: kind, intent: TestWidgetConfigurationIntent.self, provider: TestEntryProvider() ) { entry in TestWidgetFamilyView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) } .configurationDisplayName("Test Widget") .description("Test widget to try to get intents working") .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) } } public struct TestIntent: AppIntent { public static var title = LocalizedStringResource("Test Intent") public init() {} public func perform() async throws -> some IntentResult { print(String(describing: Self.self) + " perform") return .result() } } @available(iOS 17.0.0, *) public struct TestWidgetFamilyView: View { var entry: TestEntry @Environment(\.widgetFamily) var family: WidgetFamily private var defaultView: TestWidgetButtonView { return TestWidgetButtonView(entry: entry) } public var body: some View { switch family { case .systemSmall: TestWidgetButtonView(entry: entry) case .systemMedium: TestWidgetButtonView(entry: entry) case .systemLarge: TestWidgetButtonView(entry: entry) default: defaultView } } } @available(iOS 17.0.0, *) public struct TestWidgetButtonView: View { var entry: TestEntry public var body: some View { Button(intent: TestIntent()) { Text("Test \(entry.date)") } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Mar ’25
Reply to Resolving AppIntent in the app from a widget...
That would be a very nice idea. It was the first one that I explored. Unfortunately the team that owns that code is not open to making it accessible to an external native client. I might be able to do the work myself but that is another layer of diplomacy to work through. Additionally I'm not sure how separable that code is. If I have to bring in a bunch of dependencies then it might increase the footprint of the widget unnecessarily. Right now the widget is clean and does not bring in a lot of dependencies from the monolithic app. I was really hoping I could use the same mechanism that you use to perform the code in the AppIntent in the app. This would at least solve the problem in the short term.
Topic: UI Frameworks SubTopic: SwiftUI
Jun ’25
Reply to Override RoomPlan coaching prompts...
I am using RoomCaptureView. If I use my own ARView and allocate my own RoomCaptureSession will I be able to do what I want?
Topic: Spatial Computing SubTopic: ARKit Tags:
Replies
Boosts
Views
Activity
Aug ’23
Reply to AppIntent perform method not called.
I created a simple TestWidget in my main app When I use the configurable widget (i.e. TestWidgetConfigurable) only the placeholder API gets called on TestEntryProvider and the widget shows a placeholder When I use the statically configured widget (i.e. TestWidget) then my timeline api gets called on TestEntryProvider. However when I tap the button in TestWidgetButtonView the perform button in TestIntent never gets called but the widget does refresh / reload the timeline. import AppIntents import WidgetKit import SwiftUI @available(iOS 17.0.0, *) struct TestWidgetConfigurationIntent: WidgetConfigurationIntent { static var title: LocalizedStringResource { "Alexa Test Widget" } static var description: IntentDescription { "Try to get intents working" } } public struct TestEntry: TimelineEntry { public let date: Date public init(date: Date = .now) { self.date = date } } @available(iOS 17.0.0, *) struct TestEntryProvider: AppIntentTimelineProvider, TimelineProvider { typealias Entry = TestEntry typealias Intent = TestWidgetConfigurationIntent func placeholder(in context: Context) -> TestEntry { TestEntry() } func snapshot(in context: Context) async -> TestEntry { TestEntry() } func snapshot(for configuration: TestWidgetConfigurationIntent, in context: Context) async -> TestEntry { await snapshot(in: context) } func timeline(in context: Context) -> Timeline<TestEntry> { let currentDate = Date.now let nextRefresh = Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)! let entry = TestEntry() let entries: [TestEntry] = [entry] let timeline = Timeline(entries: entries, policy: .after(nextRefresh)) return timeline } func timeline(for configuration: TestWidgetConfigurationIntent, in context: Context) async -> Timeline<TestEntry> { timeline(in: context) } func getSnapshot(in context: Context, completion: @escaping @Sendable (TestEntry) -> Void) { completion(TestEntry()) } func getTimeline(in context: Context, completion: @escaping @Sendable (Timeline<TestEntry>) -> Void) { completion(timeline(in: context)) } } @available(iOS 17.0.0, *) public struct TestWidget: Widget { static let widgetKind = "TestWidget" let kind: String = Self.widgetKind public init() {} public var body: some WidgetConfiguration { StaticConfiguration( kind: kind, provider: TestEntryProvider() ) { entry in TestWidgetFamilyView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) } .configurationDisplayName("Test Widget") .description("Test widget to try to get intents working") .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) } } @available(iOS 17.0.0, *) public struct TestWidgetConfigurable: Widget { // Note: This is the same as AlexaSmartHomeWidgetConfigurable.widgetKind static let widgetKind = "TestWidget" let kind: String = Self.widgetKind public init() {} public var body: some WidgetConfiguration { AppIntentConfiguration( kind: kind, intent: TestWidgetConfigurationIntent.self, provider: TestEntryProvider() ) { entry in TestWidgetFamilyView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) } .configurationDisplayName("Test Widget") .description("Test widget to try to get intents working") .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) } } public struct TestIntent: AppIntent { public static var title = LocalizedStringResource("Test Intent") public init() {} public func perform() async throws -> some IntentResult { print(String(describing: Self.self) + " perform") return .result() } } @available(iOS 17.0.0, *) public struct TestWidgetFamilyView: View { var entry: TestEntry @Environment(\.widgetFamily) var family: WidgetFamily private var defaultView: TestWidgetButtonView { return TestWidgetButtonView(entry: entry) } public var body: some View { switch family { case .systemSmall: TestWidgetButtonView(entry: entry) case .systemMedium: TestWidgetButtonView(entry: entry) case .systemLarge: TestWidgetButtonView(entry: entry) default: defaultView } } } @available(iOS 17.0.0, *) public struct TestWidgetButtonView: View { var entry: TestEntry public var body: some View { Button(intent: TestIntent()) { Text("Test \(entry.date)") } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Mar ’25
Reply to AppIntent perform method not called.
I was finally able to get the TestIntent to work in the main app but still can't get the widget linked in from the static library to work.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Mar ’25
Reply to AppIntent perform method not called.
I converted the static library that contains the widget code into a dynamic library and this solves the problem.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’25
Reply to Resolving AppIntent in the app from a widget...
That would be a very nice idea. It was the first one that I explored. Unfortunately the team that owns that code is not open to making it accessible to an external native client. I might be able to do the work myself but that is another layer of diplomacy to work through. Additionally I'm not sure how separable that code is. If I have to bring in a bunch of dependencies then it might increase the footprint of the widget unnecessarily. Right now the widget is clean and does not bring in a lot of dependencies from the monolithic app. I was really hoping I could use the same mechanism that you use to perform the code in the AppIntent in the app. This would at least solve the problem in the short term.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
Boosts
Views
Activity
Jun ’25