在 Xcode 11 上,如何在后台配置 Intent 到 运行?

On Xcode 11, how can I configure an Intent to run in the background?

TL;DR

在 iOS 13 和 Xcode 11 上,如何在后台将 Intent 配置为 运行 并且仅 return 结果,以便可以使用作为快捷方式应用中其他操作的输入?

我想要实现的目标的详细信息

我的应用程序有一个我想通过快捷方式公开的歌曲列表(实际上,是关于歌曲的元数据,而不是歌曲本身)。这个想法是为高级用户提供一种将此音乐数据库与他们想要的其他应用程序或操作集成的方法。例如,获取下个月即将播放的音乐列表并使用它为每首歌曲创建日历事件可能很有用。在快捷方式应用程序上访问此列表可以使他们能够执行此操作。

我创建了一个名为“列出所有未读音乐版本”的 Intent,并将其响应定义为包含每首歌曲信息的 objects 列表。问题是,当我转到“快捷方式”应用程序时,使用此 Intent 创建一个新的快捷方式,然后 运行 它会打开我的应用程序,而不是在后台 运行ning。

我创建和配置 Intents 的步骤

以下是我在项目中配置 Intents 所做的高级定义。下一节将有实际的源代码和屏幕截图。

  1. 创建了一个新的 SiriKit Intent 定义文件。
  2. 创建了一个新的 Intent。
    • 定义了它的标题、描述、参数,并禁用了“Intent is eligible for Siri Suggestions”复选框。
    • 将响应 属性 定义为数组(因为它将是歌曲列表),并将输出配置为此数组 属性。
  3. 创建了一个新的 Intents 扩展,禁用了复选框“包含 UI 扩展”。这里的想法是在后台处理用户请求并 return 包含结果的列表 - 不需要 UI。
  4. 在 Intents Extension 目标中,使用在步骤 2 中创建的意图名称在 Info.plist 中定义了 IntentsSupported 数组。
  5. 使 IntentHandler class 实现为步骤 2 中创建的意图生成的协议。

代码示例和屏幕截图

我的 SiriKit Intent 定义文件和 GetUnreadReleases Intent:

GetUnreadReleases Intent 响应:

Intents 扩展 IntentHandler class:

import Intents

class IntentHandler: INExtension, GetUnreadReleasesIntentHandling {

    func handle(intent: GetUnreadReleasesIntent, completion: @escaping (GetUnreadReleasesIntentResponse) -> Void) {
        let response = GetUnreadReleasesIntentResponse(code: .success, userActivity: nil)
        let release1 = IntentRelease(identifier: "1", display: "Teste 1")
        release1.name = "Name test 1"
        release1.artist = "Artist test 1"
        response.releases = [release1]
        completion(response)
    }

    func resolveMediaType(for intent: GetUnreadReleasesIntent, with completion: @escaping (IntentMediaTypeResolutionResult) -> Void) {
        if intent.mediaType == .unknown {
            completion(.needsValue())
        } else {
            completion(.success(with: intent.mediaType))
        }
    }

    override func handler(for intent: INIntent) -> Any {
        // This is the default implementation.  If you want different objects to handle different intents,
        // you can override this and return the handler you want for that particular intent.
        
        return self
    }
    
}

Intents 扩展 Info.plist 文件:

结论

所以,我希望这个意图在后台 运行,assemble 基于用户定义参数的歌曲列表,return 这个列表用作快捷方式应用中其他操作的输入。

以前版本的 Intents 编辑器 (Xcode < 11 / iOS < 13.0) 似乎有一个复选框“支持后台执行”,但我找不到Xcode 11.

感谢来自 Apple Developer Forums 的 edford,我能够让它工作。在意图定义文件中,必须选中 "Intent is eligible for Siri Suggestions" 复选框才能使后台执行工作。