AppIntent|可以直接调用主 App 中的 ViewModel 方法

一个常见的错误(包括主流 AI 工具)是:Intent 运行独立的 Extension 进程,无法访问主 App 中定义的方法—— 这是错误的。

早期的 SiriKit Intents(iOS 16+)确实是这样,但从 iOS17 开始,新的 SiriKit Intents 运行在主 App 进程内,因此可以直接访问 App 数据,可以访问 ViewModel 单例。

App Intent 能力边界

对于 iOS 17 中新添加的 AppIntent,是这样的:

  1. 默认运行在主 App 中,可以直接通过快捷指令或者 Live Activity 中的 Button 调用。例如取件喵 App 中的 AnalyzeImageIntent 组件,并未添加到 Extension 目标。
  2. 仅当需要通过小组件的 Button 调用这个 Intent 的时候,才需要添加到 Extension 目标中。

小组件调用的 App Intent(特殊情况)

在取件喵 App 项目中,为了在小组件中快速标记取件码为已取,我创建了 MarkPickupCompletedIntent 这个组件。

Widget 和主 App 进程是完全独立的。要让 Widget 可以调用 MarkPickupCompletedIntent,它必须被添加到 Extension 目标中:

如果要让 MarkPickupCompletedIntent 可以直接调用 PickupViewModel,则 PickupViewModel 也必须被添加到 Extension 目标中,这会进一步导致 PickupViewModel 依赖的组件也需要被添加到 Extension 目标中。

因此,对于这种情况,Claude 和 GPT 的建议都是在这个 Intent 中实现完整的网络请求,并将 Token 通过 UserDefault + AppGroups 的方式传递(或者 KeyChain)。

这虽然会带来重复的代码,但毕竟是极少数情况,可以接受。