AppIntents don't show up in Shortcuts app when in SPM package

Hi there,

I successfully created an AppIntent for our app, and when I had it in the same target as our main app it showed up fine in the shortcuts app.

Then I realized that many of the new System Control widgets introduced in iOS 18 (e.g. lockscreen, control center) live in the widget extension target, but they also need to reference that same AppIntent. So to fix this, I thought I'd migrate out the code into it's own SPM package that both the WidgetExtension and the Main App processes can reference. However, after doing that and rebuilding, the intent no longer shows up in the Shortcuts app. Furthermore, my AppShortcutsProvider class now has this error when trying to define the list of appShortcuts:

App Intent <name> should be in the same target as AppShortcutsProvider

Is this intended, and if so, how do we reference the same AppIntent across multiple targets?

Answered by DTS Engineer in 797239022

When defining your types for App Intents in a different module, take care to make sure that you have a type conforming to AppIntentsPackage in both the module containing the types, as well as the module referring to those types. This is one of the most overlooked elements when setting this up.

Only framework types are supported for the module, and I suggest sticking to Xcode targets for that. Swift packages, in their default configuration, can link as either a static library or a dynamic library, depending on the surrounding build context to make an optimal choice, and that is our general recommendation for packages, but in this scenario for App Intents, means you might link as a static library, rather than as a dynamic library. Further, if you compare the build log for an Xcode framework target and for a Swift package target congigfued to be dynamic using Xcode 16 beta 4, you'll also notice that the Xcode framework target has a build step for extracting app intent metadata that the Swift package build does not. This intent metadata extraction step is important.

how do we reference the same AppIntent across multiple targets?

One thing you can do is include the source file in multiple targets, like a main app target and an app extension target.

— Ed Ford,  DTS Engineer

I have opened a feedback for this, including a sample project: FB14323687

Accepted Answer

When defining your types for App Intents in a different module, take care to make sure that you have a type conforming to AppIntentsPackage in both the module containing the types, as well as the module referring to those types. This is one of the most overlooked elements when setting this up.

Only framework types are supported for the module, and I suggest sticking to Xcode targets for that. Swift packages, in their default configuration, can link as either a static library or a dynamic library, depending on the surrounding build context to make an optimal choice, and that is our general recommendation for packages, but in this scenario for App Intents, means you might link as a static library, rather than as a dynamic library. Further, if you compare the build log for an Xcode framework target and for a Swift package target congigfued to be dynamic using Xcode 16 beta 4, you'll also notice that the Xcode framework target has a build step for extracting app intent metadata that the Swift package build does not. This intent metadata extraction step is important.

how do we reference the same AppIntent across multiple targets?

One thing you can do is include the source file in multiple targets, like a main app target and an app extension target.

— Ed Ford,  DTS Engineer

I have found that attempting to do this and use AppIntents that live in a static framework also does not work with AppShortcuts.

A static framework is still a static library at the heart of things, and you need the contents of the framework to be a dynamic library. I realize I didn't clarify that point previously.

—Ed Ford,  DTS Engineer

Regarding static vs dynamic, are you simply referring to the Mach-O Type setting or are you referring to something else? I have the framework target set to Dynamic and compilation still fails. It should be set that way in the sample projected provided in FB14507102.

Let me know if there's something else I'm missing here, but this seems like a bug.

Hey Ed ( @DTS Engineer) appreciate the response. I tried your suggestion, and I'm hitting an error when I try and run the intent: WFActionErrorDomain error 16. I'm not really sure what this means and there's no info on it.

While rewatching the "Migrate custom intents to App Intents" WWDC to see if I missed anything I noticed the speaker said "App Intents cannot be added to a framework target", which seems to contradict what you said earlier. Any advice (picture of the WWDC video attached)?

https://developer.apple.com/videos/play/tech-talks/10168 @ 7:25

I'm hitting an error when I try and run the intent: WFActionErrorDomain error 16. I'm not really sure what this means and there's no info on it.

That error domain is internal to Apple's frameworks, so there isn't documentation on it, since it's not part of the public SDK. If you have another buildable project that reproduces it that you can link to, I can look to see if there's a specific configuration in your code that is the culprit.

While rewatching the "Migrate custom intents to App Intents" WWDC to see if I missed anything I noticed the speaker said "App Intents cannot be added to a framework target", which seems to contradict what you said earlier.

Things change 😀. See the update at the end of WWDC24 What's new in App Intents.

However, I want to highlight a subtly here. While an app intent can be in a framework that is dynamically linked (with Mach-O Type set to dynamic in the framework's build settings), those intents which back App Shortcuts cannot be in a framework. That is because the AppShortcutsProvider needs to be in the main app target, and the app intents declared by this provider also need to be in the same target. This is where it's useful to include the intent's source code file into your main app target and into an extension point target (and not a framework target) if you need the intent behind an App Shortcut to also be available from an extension executable. (And enhancement requests are welcome for allowing intents used by App Shortcuts to be placed in a framework.)

—Ed Ford,  DTS Engineer

However, I want to highlight a subtly here. While an app intent can be in a framework that is dynamically linked (with Mach-O Type set to dynamic in the framework's build settings), those intents which back App Shortcuts cannot be in a framework. That is because the AppShortcutsProvider needs to be in the main app target, and the app intents declared by this provider also need to be in the same target. This is where it's useful to include the intent's source code file into your main app target and into an extension point target (and not a framework target) if you need the intent behind an App Shortcut to also be available from an extension executable. (And enhancement requests are welcome for allowing intents used by App Shortcuts to be placed in a framework.)

Thank you Ed for the much needed clarification and for your willingness to look into that FB. I would humbly ask that this rather important distinction be reflected in the docs either for AppIntentPackage, AppIntent, AppShortcuts or all of the above.

I understand that there's some wizardry that goes on allowing AppShortcutsProvider to work, but given the express support for AppIntentsPackage and AppIntents in frameworks, this seems like a rather large omission. I have filed an enhancement request for this support FB14857658.

SiriTipView in SwiftUI and UIKit both require a reference to the singular AppIntent that is already tied to the AppShortcutsProvider. Given the above, it means that the SiriTipView also has to live in the app target or app extension target. This means that any application that hosts its UI-code in a framework cannot support this use case (which is a lot of applications). So I think there's a good case here for usefulness in supporting framework-based AppIntents in Shortcuts.

So I think there's a good case here for usefulness in supporting framework-based AppIntents in Shortcuts.

I completely agree! Thank you for opening FB14857658, I left a note on it referencing some of the work I did to research these questions.

— Ed Ford,  DTS Engineer

@reed.1325 , following up on your comments inline on the above post regarding FB14857658:

I'm sorry about the confusion here — we had a mix up on our end for that bug report. I had caught the mistake before your post here, though the info was already sent back to you on the report by the time I caught it. I see your updated notes on the report. I'll handle the rest internally, we do understand already that your needs here aren't met with Xcode 16 beta 6.

— Ed Ford,  DTS Engineer

Really appreciate you clearing that up and ensuring the proper visibility for that feedback. Thank you!

Hi Ed ( @DTS Engineer) thanks for this super helpful info.

Just wanted to ask a follow-up question on the optimal way apple recommends handling AppIntentsExtension?

I currently have an AppIntentsExtension which contains my AppShortcutsProvider and AppIntent, and those are not compiled into my main app.

Currently, this works fine, but my main issue is I am not able to call updateAppShortcutParameters from my main app to tell iOS to requery my parameters for my sirishortcuts.

What is the recommended way for me to solve this, should I create a framework with those app intents and shortcut provider, and link the framework in both the AppIntentsExtension and main app?

or should I try just have the file in one of them, and adding those files as targets to both the AppIntentsExtension and main app?

Any help is greatly appreciated!

Hello @eclair4151, The information you're looking for is inline one of my posts above. To quote it here:

That is because the AppShortcutsProvider needs to be in the main app target, and the app intents declared by this provider also need to be in the same target.

With that set up, you can then call updateAppShortcutParameters() on that provider from the main app target.

Do you need any further clarifications?

—Ed Ford,  DTS Engineer

Hello @DTS Engineer , could you please explain how could we put AppIntents into a different framework using AppIntentsPackage and then use/register them from main app target without violating the rule: "AppShortcutsProvider needs to be in the main app target, and the app intents declared by this provider also need to be in the same target"? For me it looks like there is no way at all to implement AppIntent somewhere else except main app target.

Lost an hour to that missing doco re: AppShortcuts exposed intents must reside in the main target, not a dynamically linked xcframework. I've noticed that a parameterized AppIntent registered as an AppShortcut and that uses an AppEnum located in that xcframework will work for Siri and Shortcuts triggers, but does throw an SSU warning about a missing symbol.

Are there other gotchas?

The limitation — that our primary user exposed intents cannot be in that xcframework — is a drag if one maintains multiple apps that may share some limited overlapping functionality. Is there work to change this?

The AppIntentsPackage API has had a rocky public introduction since iOS 17.

AppIntents don't show up in Shortcuts app when in SPM package
 
 
Q