如何将AppIntent添加到应用程序目标并在交互式小部件中使用它

9
如何创建一个在应用程序进程中运行并在小部件的按钮中使用的AppIntent?我创建了一个新文件,将其添加到我的应用程序目标中,创建了我的AppIntent结构,然后在我的小部件中添加了一个按钮:Button(intent: TestIntent()) { Text("Test") }。这导致了一个编译时错误Cannot find 'TestIntent' in scope,这是有道理的,因为我尝试在小部件扩展中使用它的代码不存在。但是关于向小部件添加交互性的文档中提到:

对于小部件,创建一个新的结构体,采用AppIntent协议,并将其添加到您的应用程序目标中... 在协议的必需perform()函数中,添加您想要在小部件中提供的操作的代码。

如果您采用AppIntent协议,可以将自定义的应用程序意图添加到小部件扩展目标或应用程序目标中。将其添加到应用程序目标中更好,因为您可以在应用程序中重复使用添加到小部件中的按钮或切换。

当用户在您的小部件中与按钮或切换进行交互时,系统会在您的应用进程中运行perform()函数。
5个回答

5
在测试中,我已经能够确定,至少目前为止:
- 如果您不想在应用程序中重复使用应用意图,而只想在交互式小部件中使用它,您可以将您的`AppIntent`结构添加到小部件扩展目标中。通过这种设置,意图将始终在小部件进程中运行。 - 如果您希望您的应用程序意图在应用程序和小部件中可重用,您可以将您的`AppIntent`结构添加到应用程序和小部件扩展目标中。通过这种设置,如果您的应用程序正在运行(即使在后台挂起),意图将在应用程序进程中运行;当您的应用程序未运行时,意图将在小部件进程中运行。 - 尽管文档暗示了另外一种情况,但似乎无法创建一个简单的`AppIntent`,使其始终在应用程序的进程中运行,除非您实现`openAppWhenRun`,这将导致您的应用程序回到前台,或者您实现其他意图协议:`AudioIntent`、`LiveActivityIntent`、`ForegroundContinuableIntent`。这些意图类型在应用程序的后台进程中运行。
我提交了FB12584468,要求更新文档以解释要求并澄清其工作原理(或修复错误,如果这不是预期行为)。
感谢Mastodon上的Michael澄清了这个行为!“如果您需要强制在您的应用程序中运行一个应用程序意图,并且它与描述的任何路径都不匹配...我很想知道并了解您的使用情况。”

1
我也遇到了同样的问题。我猜这只是Beta版本的一个bug,因为它似乎与文档相矛盾。
我找到了一个解决方法(截至Xcode beta 5,iOS17 beta 4)。如果你实现AudioPlaybackIntent而不是AppIntent,那么它总是在应用程序的进程内启动。

1
截至15.0 beta 7版本,LiveActivityIntent按预期在主应用程序进程中运行。

1
我找到了一个更好的互动活动解决方案。
  1. 你可以创建一个名为LiveActivityIntent的结构体,然后将其添加到小部件目标和应用程序目标中。
  2. 创建两个文件,一个添加到小部件目标,另一个添加到应用程序目标,每个文件都扩展你的Intent并编写一个相同的函数。小部件目标函数可以为空,应用程序目标函数是真正的代码。在perform中调用你在扩展文件中的函数。
以上步骤确保编译成功,并且在互动意图时,系统将在应用程序进程中执行你的真正代码。

2
你能给一个代码示例吗? - soundflix

0
我们可以尝试使用AppIntentsPackage API。
  1. 创建一个 MyIntent 框架
  2. 定义一个 TestIntent
  3. // MyIntent.framework
    public struct TestIntent: AppIntent {
     static var title: LocalizedStringResource = "xxx"
    
    
     func perform() async throws -> some IntentResult {
         ...
         return .result()
     }
    }
    
    public struct TestIntents: AppIntentsPackage {}
    
  4. 在 App 或 Widget 目标中导入 MyIntent.framework

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接