I have an app with a shared internal framework, a main app target, and a widget target. In my shared framework, I have an AppIntent, FooIntent. In addition, I have an AppIntentPackage
public struct FooIntentsPackage: AppIntentsPackage { }
also in the framework. Finally, in the widget target, I reference that package:
struct FooAppIntents: AppIntentsPackage {
static var includedPackages: [any AppIntentsPackage.Type] { [ FooIntentsPackage.self ] }
}
However, when I run this, I get a bunch of these errors:
metadata `_$s8Internal15FooAppIntentsV' did not match any imported symbol.
I've tried turning off Strip Linked Product in both the Framework and the Widget, to no avail. Any ideas?
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
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
https://medium.com/@giulio.caggegi/use-app-intents-with-ios-16-90a341ccbc94
I create a demo according this article,
and add the App Intents in Shortcuts App ,
then add a Scripting "Get text from xxx" ,
but the result is Empty,
how could I modify the AppEntity or add which attribute,
so the Scripting "Get text from xxx" can get text from the App Intents?
So, I've declared an AppIntent that indicates my app can "Open files" that conform to UTType.Image.
I've got a @AssistantEntity(schema: .files.file) and a
@AssistantIntent(schema: .files.openFile) declared.
So I navigate to the files app, quicklook an image, and open type-to-siri.
I tell siri "open this in " and all it does is act like "open ". No breakpoint is hit in my intent's perform method.
Am I doing something wrong? How can I test these cross-app behaviors?
Are they... not actually possible? Does an "OpenIntent" only work on my app's own URLs and not on file URLs from other apps?
@available(iOS 18.0, *)
@AssistantIntent(schema: .system.search)
struct SearchIntent: AppIntent {
static let title: LocalizedStringResource = "Search <app name redacted>"
static let searchScopes: [StringSearchScope] = [.general]
@Parameter(title: "Criteria")
var criteria: StringSearchCriteria
@MainActor
func perform() async throws -> some IntentResult {
MyDependencyManager.shared.performSearch(with: criteria.term)
return .result()
}
}
// In AppShortcutProvider
AppShortcut(
intent: SearchIntent(),
phrases: [
"Find \(\.$criteria) in \(.applicationName)",
"Search for \(\.$criteria) in \(.applicationName)",
],
shortTitle: "Search <app name redacted>",
systemImageName: "magnifyingglass"
)
The search works when using the Shortcuts app, but not when using Siri. For example if I ask Siri "Search for in " it just does a Google search or prompts me to install the app from the App Store (I am running a debug build via Xcode). I can't get this to work from Spotlight either.
I am using Xcode 16 and running the app on an iPhone 16 with OS 18.2 beta and Apple Intelligence turned on.
What am I doing wrong here? I cannot find any other information about this intent or how to properly set it up and use it.
Hello everyone,
I'm currently working on an App Intent for my iOS app, and I’ve encountered a frustrating issue related to how Siri prompts for a category selection. Here’s an overview of what I’m dealing with:
extension Category: AppEntity, @unchecked Sendable {
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(name)")
}
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Category")
typealias DefaultQueryType = ShortcutsCategoryQuery
static var defaultQuery: ShortcutsCategoryQuery = ShortcutsCategoryQuery()
}
struct ShortcutsCategoryQuery: EntityQuery {
func entities(for identifiers: [String]) async throws -> [Category] {
let context = await ModelContext(sharedModelContainer)
let categories = try CategoryDataProvider(context: context).getItems()
return categories.filter { identifiers.contains($0.id) }
}
func entities(matching string: String) async throws -> [Category] {
return try await suggestedEntities()
}
func suggestedEntities() async throws -> [Category] {
let context = await ModelContext(sharedModelContainer)
do {
let categories = try CategoryDataProvider(context: context).getItems()
if categories.isEmpty {
print("No categories found.")
}
return categories.map { category in
Category(
id: category.id,
name: category.name,
stringSymbol: category.stringSymbol,
symbol: category.symbol,
stringColor: category.stringColor,
color: category.color
)
}
} catch {
print(error)
return []
}
}
}
The issue arises when I use Siri to invoke the intent. Siri correctly asks me to select a category but does not display any options unless I said something that Siri recognized, like "Casa(House) or Teste(Test)" in portuguese. Only then does it show the list of available categories.
I would like the categories to appear immediately when Siri asks for a selection. I've already tried refining the ShortcutsCategoryQuery and debugging various parts of my code, but nothing seems to fix this behavior.
Hello. I am having trouble trying to create a control in control center view that opens a specific view in my app using AppIntents (iOS18 )and WidgetKit, can someone help me please? I feel like the original videos and documentations are incomplete.
I'm returning the following result in one of my AppIntents:
return .result(value: "Done!", dialog: IntentDialog("Speed limit \(speedLimit)"))
With iOS 18.0.1 it was nicely confirming the user the result of their command by saying e.g. "Speed limit 60" and showing it on top of the screen.
With iOS 18.1, it only shows/says "That's done" or "Done" at the bottom of the screen.
Am I missing something that changed in the AppIntents API since iOS 18.1?
Issue
When triggering an App Intent using assistant schemas from Apple Intelligence (voice or text) the App opens without prompting for search criteria.
How to repeat
This can be repeated in the example provided by Apple here: https://developer.apple.com/documentation/appintents/making-your-app-s-functionality-available-to-siri
Download the sample code
Build and run on Xcode 16.1 beta 3
Target iPhone 15 Pro Max on iOS 18.1 beta 7
Trigger Apple Intelligence
Enter prompt: "Search AssistantSchemasExample"
Expected behaviour
Apple Intelligence should prompt the user for the criteria and provide this to the App so that the experience is seamless for the end-user. Otherwise Assistant Intents are nothing more than deep links to search screens.
Notes
The example uses @AssistantIntent(schema: .photos.search) intent.
And I've found the issue is also present in other search intents:
@AssistantIntent(schema: .system.search)
@AssistantIntent(schema: .browser.search)
Questions
Has anyone managed to get the prompt to appear?
Will this only function on iOS 18.2?
Hi devs,
my app has control center widgets and interactive widgets, both are using the same app intent to update sharing status (App Group's UserDefault).
When the app is running in the background, control center widget and interactive widgets can be reloaded with correct status. However, if the app is not running in the background, I tap the interactive widget and the interactive widget can reload with correct status but the control center widget can't. Vice versa, the control center widgets can reload with correct status but the interactive widgets can't.
struct ChangeAppStatusIntent: AudioRecordingIntent, CustomIntentMigratedAppIntent, PredictableIntent, LiveActivityIntent, SetValueIntent {
... // data and setup
@MainActor
func perform() async throws -> some IntentResult {
// change the AppGroup data for app status
WidgetCenter.shared.reloadAllTimelines()
ControlCenter.shared.reloadAllControls()
}
}
does any way to fix this issue?
I'm converting my app to use the new AppIntent system in the widgets from the old custom intent based system. I'm trying to implement defaultResult in my EntityQuery, so the widget can be ready to go as soon as it's added to the home screen.
https://developer.apple.com/documentation/widgetkit/making-a-configurable-widget
https://developer.apple.com/documentation/appintents/uniqueappentityprovider/defaultresult()
But the weird behavior is that defaultResult seems to be called once when the first widget is added to a home screen, and shows the correct data, but then the defaultResult method is never called again when subsequent widgets are added.
It just uses the result from when the first widget was added. This especially causes issues because then a user will delete the item that the first widget was referencing, but adding new widgets still try to refer to the old AppEntity that no longer exists, even though "entities(for " returns nil for those IDs to signify that item no longer exists.
I would have assumed defaultResult would get called every time a new widget is added, but haven't seen anyone else complain about this. Has anyone seen this issue before or have any advice?
Hello,
I am implementing an App Intent which asks the user for a currency amount:
private func loadAmountList(forNumber number: String) async throws -> [NSDecimalNumber] {...}
@MainActor func perform() async throws -> some IntentResult & ShowsSnippetView {
let list = try await loadAmountList(forNumber: fixedNumber).compactMap {
currencyFormatter.string(from: $0)
}
throw $amount.needsDisambiguationError(among: list, dialog: "app_intent_sim_amount_prompt")
}
If I start this intent from Siri, the attached screenshot is shown, but no matter what I say ("10 EURO", "ten", "10", "10€"...) Siri never understands anything and keep reshowing the dialog over and over again.
If instead I tap any of the choices then the intent execution proceeds currectly.
How can I solve the problem?
Thanks
Hello,
I am implementing an App Intent which shows a confirmation dialog before proceeding with the operation execution.
It works fine when the intent is started from a shortcut, but it always fails when started from Siri: I obtain the error message depicted in the attached screenshot ("An error occurred, try again").
That message appears as soon as the requestConfirmation method is called in the perform method of my App Intent:
try await requestConfirmation(actionName: .do, dialog: "app_intent_sim_confirmation_message") {
SIMRechargeIntentSummaryView(...)
}
...
How can I solve the problem?
Thanks
Is anyone else seeing their apps crash on iOS/macOS 17.4/14.4 and newer when building a project that simply just includes the iOS 18 @AssistantIntent Macro?
The beta 4 releases still have this problem. There are no notes about this that I have seen in the beta release notes. Crash message shown in console when trying to run on 17.4, 17.5, 17.5.1, etc:
dyld[21935]: Symbol not found: _$s10AppIntents15AssistantSchemaV06IntentD0VAC0E0AAWP Referenced from: <F7A1FEF0-F3B0-379C-A914-D1FB0BA7C693> /Users/jonathan/Library/Developer/CoreSimulator/Devices/CA308F47-BCA8-4429-8599-1BB1CCEAB5B6/data/Containers/Bundle/Application/D7DC8E16-90DB-406A-A521-20F18326E4A7/IntentDemo.app/IntentDemo.debug.dylib Expected in: <88E18E38-24EC-364E-94A1-E7922AD247AF> /Library/Developer/CoreSimulator/Volumes/iOS_21F79/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/AppIntents.framework/AppIntents
Obviously, the new Apple Intelligence AssistantIntents only work on the 2024 OS releases. However, even when these new App Intents are marked with @available(iOS 18, macOS 15, *), the app crashes on any earlier OS version. But it runs just fine on iOS 18 and macOS 15...
I would love for me to just have done something wrong but I don’t think I have… Here is the sample project: https://github.com/JTostitos/FB14323923
Maybe it's a compiler issue thats failing to strip out the macro when building for older OS's or an Xcode issue - I have no idea. I just would like to know why its not working and how to resolve it.
Thanks in advance for anyones help...
I am trying to get Controls working using AppIntents.
My Intents make use of @Dependency, which get set up during application launch using AppDependencyManager.shared.add { ... }. When the app has been launched, my Controls work fine.
However, when the app gets killed using the app switcher or by the system, my Controls cease to work.
Checking in Console.app, I found the following:
PROGRAMMING ERROR: Failed to retrieve dependency of type {my dependency}. Please register your dependency
with AppDependencyManager before performing a dependent intent.
My intents use openAppWhenRun = true, so I don't understand why the dependencies are not registered when running the Intent.
Alternatively, I would like to know how to register AppDependencies in a Widgets Extension.
I have encountered a problem about AppEntity and AppIntent shortcut. Here is what i have done.
I created some shortcuts use AppShortcutsProvider. Each shortcut created by AppEntity.
I search my app name in spotlight, so these shortcut can be shown in the spotlight.
I don't click the shortcut and back to home screen. Then I delete these shortcuts by modify the Entity.defaultQuery and call AppShortcutsProvider.updateAppShortcutParameters()
Going back to the spotlight, I can see my previous query and result. When I clicked the shortcut, I got an error WFBackgroundShortcutRunnerErrorDomain
Should the spotlight result need to be refreshed when i come back to it?
Hello,
I have written the following app intent and I can access it via shortcuts. But I can't get Siri to pick it up. I want it to have a dynamic book title (which could be anything) so that the user can say "Add (bookname) to my (app name). I need it to work for ios 17.1 onwards. I have added siri as a capability for my ios app.
import AppIntents
struct AddBookToReadingListIntent: AppIntent {
static var title: LocalizedStringResource = "Add my Book"
@Parameter(title: "Book Title", requestValueDialog: "What's the title of the book you want to add?")
var bookTitle: String
static var parameterSummary: some ParameterSummary {
Summary("Add my '\(\.$bookTitle)'")
}
func perform() async throws -> some IntentResult & ReturnsValue<String> {
return .result(value: "Added '\(bookTitle)' to your app")
}
}
struct AppShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: AddBookToReadingListIntent(),
phrases: [
"Add \(\.$bookTitle) in \(.applicationName)"
],
shortTitle: "Add Book to app name",
systemImageName: "book"
)
}
}
I am currently working on integrating an app with Siri, adding support for starting VOIP calls and sending messages. Although it is understood it is recommended to use SiriKit for calling and messaging, I would like to allow users to select a profile to use for calling. As far as I am aware the notion of selecting a profile to call from is not something SiriKit supports, therefore, it was decided to go with App Intents to allow for more control over the parameters utilized to start calls.
After integrating VOIP calling with App Intents, I noticed CallKit is not able to start calls when the App Intent is invoked from the background. I get the following error:
Error Domain=com.apple.CallKit.error.requesttransaction Code=6 "(null)”
This seems to correspond to the CXErrorCodeRequestTransactionError invalidAction. This error only happens when the intent is invoked from the background. Changing the App Intent property openAppWhenRun to true solves the issue as it brings the app to foreground before running the intent.
However, I would like to support starting calls from the background to avoid making users unlock their phones prior to starting a call with Siri to make it a truly hands-free experience. I suspect the desired behavior is possible, most likely with SiriKit, as some famous VOIP calling apps (i.e. WhatsApp, Messenger, etc) exhibit the behavior I described. However, is there any way to start calls from the background with App Intents? Or is the desired behavior something exclusive to SiriKit?
I have pasted three code snippets below that can replicate the issue. At the moment I am on Xcode Version 15.3, macOS Sonoma 14.6.1, and testing on iOS 16.6.1
To demonstrate the issue I have created the following CXProviderDelegate:
class CallManager: NSObject, CXProviderDelegate {
func startCall() {
let callKitProvider = CXProvider(configuration: CXProviderConfiguration())
callKitProvider.setDelegate(self, queue: nil)
let callKitController = CXCallController()
let recipient = CXHandle(type: .generic, value: "Demo Outgoing Call")
let uuid = UUID()
let startCallAction = CXStartCallAction(call: uuid, handle: recipient)
let transaction = CXTransaction(action: startCallAction)
callKitController.request(transaction) { error in
if let error {
print(error)
} else {
print("no errors")
}
}
callKitProvider.reportOutgoingCall(with: uuid, connectedAt: nil)
}
func providerDidReset(_ provider: CXProvider) {
// no-op, not required to demonstrate the issue
}
}
Then, I have a UIViewController that is the only screen of this example app:
class ViewController: UIViewController {
@IBOutlet weak var startCallButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
startCallButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
}
@objc func buttonTapped() {
let manager = CallManager()
manager.startCall()
}
}
As for app intents, I put together a very simple intent to trigger the start of an outgoing call:
struct StartCall: AppIntent {
static var title: LocalizedStringResource = "Start Call"
static var openAppWhenRun = false
func perform() async throws -> some IntentResult {
let manager = CallManager()
manager.startCall()
return .result()
}
}
When the UIViewController is presented and I tap the button to start a call I see the green call banner appear and "no errors" is printed to the console as intended. However, when I open the Shortcuts app and run the app intent, the green banner does not appear and the message Error Domain=com.apple.CallKit.error.requesttransaction Code=6 "(null)” is printed to the console.
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.
In iOS 17, after updating the app, when trying to "Edit Widget" from a long press on the widget, "Unknown extension process" is displayed and the widget cannot be edited. At this time, the widget becomes completely white (or completely black), and it cannot be fixed without restarting the iPhone. This issue occurs sporadically on some devices. The implementation uses AppIntentTimelineProvider. Does anyone know a solution, workaround, or the cause of this problem?
Thank you.
Was watching this latest WWDC 2023 video and had a question. I see about 17:20 in, they mention you can now put the shortcut provider in an app intent extension.
https://developer.apple.com/videos/play/wwdc2023/10103/
This works fine by itself and I can see all my shortcuts and use siri, but as soon as I try to call into the extension from the main app in order to trigger updateAppShortcutParameters() or any other code, I get a linker error. Am I doing something obvious wrong? Note, I called it a framework, but it Is just an extension. Cant figure out how I am supposed to be calling this method.
Any help is greatly appreciated!
https://developer.apple.com/documentation/appintents/appshortcutsprovider/updateappshortcutparameters()?changes=_4_8
https://imgur.com/a/yDygSVJ