Async image is not loading in app intent's view.
Image is just not loading without any error
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
200 Posts
Sort by:
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?
My team is preparing for iOS 18, and wanted to add intents using assistant schemas that are iOS 18 and above restricted.
We noticed that the result builder for AppShortcuts added support for limitedAvailabilityCondition from iOS 17.4 so we marked the whole struct as available from it.
The app compiles but writing a check like below inside appShortcuts property a crash will happen in iOS 17.5 runtime. (Removing the #available) is solving this problem.
if #available(iOS 18, *) {
AppShortcut(
intent: SearchDonut(),
phrases: [
"Search for a donut in \(.applicationName)"
],
shortTitle: "search",
systemImageName: "magnifyingglass"
)
}
We tried out putting the os check above and returning shortcuts in arrays and that both compiles and runs but then AppShortcuts.strings sends warnings that the phrases are not used (This phrase is not used in any App Shortcut or as a Negative Phrase.) because the script that extracts the phrases somehow fails to perform when shortcuts are written like below:
static var appShortcuts: [AppShortcut] {
if #available(iOS 18.0, *) {
return [
AppShortcut(
intent: CreateDonutIntent(),
phrases: [
"Create Donut in \(.applicationName)",
],
shortTitle: "Create Donut",
systemImageName: "pencil"
)
]
} else {
return [
AppShortcut(
intent: CreateDonutIntent(),
phrases: [
"Create Donut in \(.applicationName)",
],
shortTitle: "Create Donut",
systemImageName: "pencil"
)
]
}
}
This is very problematic because we can't test out on TF with external users new intents dedicated for iOS 18.
We filed a radar under FB15010828
When building and running an app on iOS 18.1 Beta 3 a fresh sample app with an @AssistantIntent will immediately crash. Using a sample Assistant Intent from the developer documentation site will cause this. Removing the @AssistantIntent macro will allow the app to run. Using Xcode 16.1 beta.
dyld[1278]: Symbol not found: _$s10AppIntents15AssistantSchemaV06IntentD0VAC0E0AAWP Referenced from: <DC018008-EC0E-3251-AAFC-5DEB51863F17> /private/var/containers/Bundle/Application/2726C2CE-0255-4692-A7CA-B343146D4A83/Runner.app/Runner.debug.dylib Expected in: <E9AF073B-B6E0-31B8-88AA-092774CEEE3D> /System/Library/Frameworks/AppIntents.framework/AppIntents
(FB14949135)
I develop a siri function with my App. In the custom intent, I choose "Create" category.
And when I run this command, create button would be displayed.
But the strange thing, when I say "create", no response. I say "yes", "okay", "sure", all of them worked. Only "create", didn't work. If we show a create button, the "create" command also need work.
Can anyone help me, I want "create" command also worked.
Has anyone figured out how to use the new OpenURLIntent intent to open their own app using a custom URL scheme?
I have the following code:
@available(iOS 18, *)
struct BarcodeScannerControlWidget: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(kind: "scannerIntent") {
ControlWidgetButton(action: OpenBarcodeScannerIntent()) {
Label("Scan Barcode", systemImage: "barcode.viewfinder")
}
}
.displayName("Scan Barcode")
}
}
@available(iOS 18, *)
struct OpenBarcodeScannerIntent: AppIntent {
static var title: LocalizedStringResource = "Scan Barcode"
func perform() async throws -> some IntentResult & OpensIntent {
let url = "myscheme:///barcodeScanner
let openURLIntent = OpenURLIntent(url)
return .result(opensIntent: openURLIntent)
}
}
Running this intent doesn't seem to do anything. If I replace the URL with say "https://www.apple.com", the intent opens up safari with that URL.
I feel like this is probably really easy and hopefully I'm just doing something stupid, but I can't get a control to open the app it belongs to.
Taking the intent itself directly from the example code, and it does nothing when the button is pressed.
struct OpenAppWidget: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(
kind: "com.dfjkldfsfrw.ControlCenterWidgetDemo.OpenApp"
) {
/// This one - based on the demo code - doesn't work on simulator or device
ControlWidgetButton(action: LaunchAppIntent()) {
Label("Launch App", systemImage: "arrow.up.right")
}
}
.displayName("Launch App")
.description("A an example control that launches the parent app.")
}
}
struct LaunchAppIntent: OpenIntent {
static var title: LocalizedStringResource = "Launch App"
@Parameter(title: "Target")
var target: LaunchAppEnum
}
enum LaunchAppEnum: String, AppEnum {
case timer
case history
static var typeDisplayRepresentation = TypeDisplayRepresentation("Productivity Timer's app screens")
static var caseDisplayRepresentations = [
LaunchAppEnum.timer : DisplayRepresentation("Timer"),
LaunchAppEnum.history : DisplayRepresentation("History")
]
}
I've tried adding a perform( function to the intent, and setting openAppWhenRun to true, but they don't seem to make a difference.
I've also tried using an OpenURLIntent in the result of the button's intent to open the app based on a custom url scheme, but whilst that seems to work in the simulator, it doesn't work on a real device.
What am I missing?
OK, so I'm trying to share some utils classes for logging. The problem is a use-case where I want to create a debug notification.
However, inside the app, I want to show a popup instead if the app is showing, but I can't share that code because it uses UIApplication.shared.ApplicationState.
I've tried gating it off with all sorts of methods, @available etc. but I get compilation error "unavailable for application extensions"
Example of me trying:
static func doNotification(_ header: String, message: String) {
//so I'm trying to gate off the code that only can be called in an extension , and in addition I have @available below
if(isAppExtension()){
doNotificationFromExtension(header, message: message)
}else{
doNotificationFromApp(header, message: message)
}
}
@available(iOSApplicationExtension, unavailable)
static func doNotificationFromApp(_ header: String, message: String) {
let state = UIApplication.shared.applicationState
if state != .active {
//my dialog handler in-app popup
}else{
NotifUtils.createLocalNotification(message, header: header, category: NOTIFICATION_CATEGORY_DEBUG, playSound: false)
}
}
//here I know that I'm in an extension, so app isn't showing - always local notification
static func doNotificationFromExtension(_ header: String, message: String) {
NotifUtils.createLocalNotification(message, header: header, category: NOTIFICATION_CATEGORY_DEBUG, playSound: false)
}
static func isAppExtension() -> Bool {
return Bundle.main.executablePath?.contains(".appex/") ?? false
}
Is there any way to share the code like this? The reason I want to do this is because I have various live activity code that I'd want to re-use, but this is a show.-stopper.
I am working on a live activity with a button that will do a network call when pressed on.
I want to make sure that it can only be pressed once, and then ignored while the request is processed.
This is what I did:
Since it seems that a new intent object is created for each button press, I am using a static synchroniser like this:
private var _isBusy: Bool = false
private var _timestamp: Date? = nil
private let queue: DispatchQueue
private let resetInterval: TimeInterval
init(resetInterval: TimeInterval = 60, queueLabel: String = "default.synchronizedBoolQueue") {
self.resetInterval = resetInterval
self.queue = DispatchQueue(label: queueLabel)
}
var isBusy: Bool {
get {
return queue.sync {
return _isBusy
}
}
set {
queue.sync {
_isBusy = newValue
}
}
}
func setIfNotBusy() -> Bool {
return queue.sync {
let now = Date()
if let timestamp = _timestamp {
if now.timeIntervalSince(timestamp) > resetInterval {
// Reset if it was more than the specified interval ago
_isBusy = false
_timestamp = nil
}
}
if !_isBusy {
_isBusy = true
_timestamp = now
return true
}
return false
}
}
func clearBusy() {
queue.sync {
_isBusy = false
_timestamp = nil
}
}
}
Then, in my intent I have:
private static let synchronizedBoolean = SynchronizedBoolean(queueLabel: "myIntent")
...
func perform() async throws -> some IntentResult {
NSLog("---LIVE perform() called")
if(!UserEventIntent.synchronizedBoolean.setIfNotBusy()){
NSLog("---LIVE Was already in progress!")
}else{
//doing intent logic here
UserEventIntent.synchronizedBoolean.clearBusy()
}
}
I am pretty new to Swift, so my hope is that someone more experienced than me could tell me if this a reasonable approach or if I'm missing anything?
A big question - let's say I go into the perform() method, and while I'm in there, the user presses the button and the intent is called again. I get the "already in progress", but the method must still provide a result. Will that effect the intent already in progress?
Thoughts much appreciated.
The action “bla bla” could not run because of an internal error on specific mobile only
I have tried updating shortcuts app and restart my phone but nothing works
In iOS 18, the requestValue method no longer works when the parameter it is called on is not included in the parameterSummary of an AppIntent. This issue causes the app to fail to present a prompt for the user to select a value, resulting in an error with the message:
Domain=NSCocoaErrorDomain Code=4099 "The connection from pid 40685 on anonymousListener or serviceListener was interrupted, but the message was sent over an additional proxy and therefore this proxy has become invalid."
Steps to Reproduce:
Create a simple AppIntent with the following code:
import AppIntents
struct Intent: AppIntent {
static let title: LocalizedStringResource = "Intent"
static var parameterSummary: some ParameterSummary {
Summary("Test \(\.$category)") {}
}
@Parameter(title: "Category")
private var category: CategoryEntity?
@Parameter(title: "Hidden Category")
private var hidden: CategoryEntity?
@MainActor
func perform() async throws -> some ReturnsValue<CategoryEntity?> {
var result: CategoryEntity?
do {
result = try await $hidden.requestValue("Select category") // Doesn't work since iOS 18 as $hidden is not set in parameterSummary
} catch {
print("\(error)")
}
return .result(value: result)
}
}
Run the code on a device with iOS 18.
Observe that the requestValue method fails to present the selection prompt and instead throws an error.
Expected Results:
The app should successfully present a prompt for the user to select a value for the hidden parameter using requestValue, even if the parameter is not included in the parameterSummary.
Actual Results:
The app fails to present the selection prompt and throws an error, making it impossible to use requestValue for parameters not included in parameterSummary.
Version/Build:
iOS 18.0
Configuration:
Tested on various devices running iOS 18.
Is there a change in the API that I might have missed?
I have a simple lock screen widget that when tapped, should open a certain flow in my app. This works fine when the main app is already running, but when tapped while the app is not running, the app launches, but it doesn't open the flow I want it to.
When I debug it (see flow below), it seems that the problem come from the widgetConfigurationIntent(of:) function on NSUserActivity. When the app is cold launched, I get the expected NSUserActitivity, but the function above returns nil. That same piece of code returns a valid WidgetConfigurationIntent if the app is already running.
Any ideas what might go wrong? There's nothing in the documentation hinting about why this might happen, so I feel a bit lost.
BTW, this is how a debug opening from scratch with a lock screen widget:
Select "Wait for the executable to be launched" in the scheme editor in Xcode.
Make sure the app is not running on device or simulator
Start debugging session in Xcode (app is built but not opened)
Lock device, tap already installed lock screen widget.
App launches and my breakpoint is hit.
Objective: When the app is running, directly operate the app without launching it. When the app is not started, wake up the app to perform the corresponding operation.
Premise: AppIntent's openAppWhenRun can dynamically control whether the app is launched, but the variable itself cannot be changed.
Therefore, the idea is to refresh the widget when the app is started or terminated, displaying different content (binding different intents) to achieve the goal.
However, there are persistent issues during code implementation.
struct ControlWidgetContent: ControlWidgetTemplate {
var body: some ControlWidgetTemplate {
if (applaunched) {
return ControlWidgetButton(action: Aintent()) {
Label("xxxx", systemImage: "calendar")
}
} else {
return ControlWidgetButton(action: Bintent()) {
Label("xxxx", systemImage: "calendar")
}
}
}
}
@available(iOS 18.0, *)
struct ControlWidgetContent: ControlWidget {
let kind: String = "ControlWidgetInterface"
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(
kind: kind
) {
ControlWidgetContent()
}.displayName("xxxx")
}
}
it preports error:
Function declares an opaque return type 'some ControlWidgetTemplate', but the return statements in its body do not have matching underlying types
Return statement has underlying type 'ControlWidgetButton<Label<Text, Image>, ControlWidgetButtonDefaultActionLabel, PlayDayRcmdIntent>'
Apple's sample code 'Trails' supports multiple scenes, however everything is using shared state across the scenes. Put the app in Split View mode and have two windows of the app running and navigate, you can see both mirror each other. Works as designed, it is using a shared 'navigation model' across all scenes.
https://developer.apple.com/documentation/appintents/acceleratingappinteractionswithappintents
I would like to know if there is a supported or recommended way to modify individual scene storage from within the perform body of an AppIntent. The objective is to have App Shortcuts that launch different tabs in a TabView or different selections in a List.
In short, I want to deep link to features, but account for more than one scene being open on iPad and only have programatic navigation happen on the scene that is 'foremost' or the 'activated' one in Split View.
I have it working with either a @Dependency or posting a Notification with my main ContentView listening to the other end, but it changes all scenes.
I'm not really sure if I'm using the right lingo here because there's so little documentation on this, so apologies in advance.
I have an app with a few custom intents that I'm attempting to transition to AppIntents. I have the newly transitioned intents showing up in the Shortcuts app as expected, however when I run them I get an immediate failure saying "The operation couldn't be completed" (see photo). Note that the "AppIntentsClient" class mentioned in the photo is the dependency I'm trying to import.
I've narrowed it down to the @Dependency that I'm using in my intent handler. At the top of the intent handler I have a line:
@Dependency
private var appIntentsClient: any AppIntentsClient // NOTE: AppIntentsClient is a protocol -- could that be the issue?
And if I comment out this line, the intent no longer throws that error.
I'm following the guidelines shown in sample apps by setting the dependency on my main app's startup in didFinishLaunchingWithOptions like so:
// gets called by the main app `didFinishLaunchingWithOptions`
func onDidFinishLaunching() {
let adapter = AppIntentsAdapter() //AppIntentsAdapter adheres to protocol AppIntentsClient
self.appIntentsAdapter = adapter
AppDependencyManager.shared.add(dependency: adapter)
MyAppShortcuts.updateAppShortcutParameters()
}
Unfortunately there is virtually no documentation around AppDependencyManager or AppDependencies in general. Both documentation pages have at most one line, but don't indicate why this would be failing for me. Is there any information out there on why these errors may be happening? I've also looked at the Console app to see if the OS logs anything, but nothing of value was found.
https://developer.apple.com/documentation/appintents/appdependencymanager
https://developer.apple.com/documentation/appintents/appdependency
I would like to call my App Intent directly from my main app target, in an effort to start a live activity in the background when I receive a silent push notification from the server.
I have seen in one of the WWDC developer lounges on Slack that this should be possible. Here is how I tried doing it: (it was recommended like that in the lounge)
let appIntent = LiveActivityRefreshIntent()
Task {
try await appIntent()
}
But I get a compiler error:
Instance method 'callAsFunction(donate:)' requires the types '(some IntentResult).Value' and 'Never' be equivalent
It's strange because as far as I can tell, I cannot declare my perform method as returning Never. Here is the signature and return value of my App Intent's perform method:
func perform() async throws -> some IntentResult {
LiveActivityController.shared.updateLiveActivities()
return .result()
}
Is there still a way to call the app intent from my code? If so, how?
Hi,
I am working with AppIntents, and have created an OpenIntent with a target using a MyAppContact AppEntity that I have created. This works fine when running from Shortcuts because it pops up a list of options from the 'suggestedEntities` method. But It doesn't work well when using with Siri. It invokes the AppIntent, but keeps repeatedly asking for the value of the 'target' entity, which you can't really pass in with voice.
What's the workaround here? Can an OpenIntent be activated by voice as well?
here's my case, i develop a control widget, user can push a controlwidget to play music without open the app.
i bind a AudioPlaybackIntent to the widget. when user click the widget, the app will receive the intent and start to play music.
it works perfect when app running in background or foreground. but when app not launched, the respond is too slow, it takes several seconds to start play music.
is there any way to make the respond faster when app not launched? if i want to do something when app not launched, what should i do?
Hi, I'm trying to implement the iOS18 ControlWidget features. When i turn on a ControlWidgetToggle that action with a LiveActivityIntent, the toggle will turn off automatic. The toggle state is read from my sharemanger, but it state won't refresh even i use the ControlCenter.shared.reloadAllControls(). Here is my code.
struct TimerLiveActivityControl: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(kind: Self.kind) {
ControlWidgetToggle(isOn: ShareManager.shared.isLiveActivityTimerOn, action: LiveActivityTimerIntent()) { isTurnedOn in
Image(systemName: isTurnedOn ? "fan.fill":"fan")
Text(isTurnedOn ? "Turned off" : "Turned On")
} label: {
Text("Live Activity Timer")
}
}
}
}
struct LiveActivityTimerIntent: LiveActivityIntent, SetValueIntent {
static var title: LocalizedStringResource { "Live Activity timer" }
@Parameter(title: "is Turned On")
var value: Bool
@MainActor
func perform() async throws -> some IntentResult {
TimerLiveActivityTimer.shared.duration = 10
TimerLiveActivityTimer.shared.startTimer()
return .result()
}
}
func startTimer() {
self.startActivity()
self.isLiveActivityTimerOn = true
Timer.scheduledTimer(withTimeInterval: TimeInterval(self.duration), repeats: false) { timer in
self.isLiveActivityTimerOn = false
ControlCenter.shared.reloadAllControls()
self.endActivity()
}
//The ControlWidgetToggle can't refresh even i refresh it all time
Timer.scheduledTimer(withTimeInterval: TimeInterval(0.1), repeats: true) { timer in
ControlCenter.shared.reloadAllControls()
}
}
However the code can work if I use a single SetValueIntent.
My Xcode version is 16.0 beta, use iOS 18.0 simulator.
I’ve set up a focus filter, but the perform() method in SetFocusFilterIntent isn't called when the focus mode is toggled on or off on my iPhone since I updated to iOS 18 beta (22A5326f).
I can reproduce the issue for my app, but focus filters are also broken for any third-party apps installed on my phone, so I guess it's not specific to how I've implemented my filter intent.
This used to work perfectly on iOS 17. I didn't change a single line of code, and it broke completely on the latest iOS 18 beta.
I've filed a bug report including a sysdiagnose (FB14715113).
To the developers out there, is this something you are also observing in your apps?