在Xcode 11中,如何配置一个意图在后台运行?

huangapple go评论78阅读模式
英文:

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

问题

TL;DR

在iOS 13和Xcode 11上,我如何配置一个Intent在后台运行并只返回结果,以便将其用作Shortcuts应用程序中其他操作的输入?

Details of what I'm trying to achieve

我的应用程序有一个歌曲列表,我希望通过Shortcuts暴露出来(实际上是有关歌曲的元数据,而不是歌曲本身)。想法是为高级用户提供一种将这个音乐数据库与其他他们想要的应用程序或操作集成的方法。例如,有人可能会发现获取下个月即将发布的音乐列表并将其用于为每首歌曲创建日历事件非常有用。在Shortcuts应用程序中访问此列表可以使他们实现这一目标。

我已经创建了一个名为“List All Unread Music Releases”的Intent,并将其响应定义为包含有关每首歌曲的信息的对象列表。问题是,当我转到Shortcuts应用程序,创建一个使用此Intent的新快捷方式并运行它时,它会打开我的应用程序而不是在后台运行。

Steps I've done to create and configure Intents

以下是我配置项目中意图的步骤的高级定义。下一部分将包含实际源代码和截图。

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

Code samples and screenshots

我的SiriKit意图定义文件和GetUnreadReleases意图:

在Xcode 11中,如何配置一个意图在后台运行?

GetUnreadReleases意图响应:

在Xcode 11中,如何配置一个意图在后台运行?

Intents扩展的IntentHandler类:

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文件:

在Xcode 11中,如何配置一个意图在后台运行?

Conclusion

因此,我希望这个意图在后台运行,根据用户定义的参数组装歌曲列表,并返回此列表以供Shortcuts应用程序中的其他操作使用。

似乎以前的Intents编辑器版本(Xcode < 11 / iOS < 13.0)有一个“支持后台执行”的复选框,可以做到这一点,但我在Xcode 11上找不到它了。

英文:

TL;DR

On iOS 13 and Xcode 11, how can I configure an Intent to run in the background and just return the result, so it can be used as the input for other actions in the Shortcuts app?

Details of what I'm trying to achieve

My app has a list of songs that I want to expose via Shortcuts (actually, metadata about the song, not the song itself). The idea is to give advanced users a way to integrate this database of music with other apps or actions they want. For example, one may find useful to get a list of upcoming music for the next month, and use it to create Calendar events for each song. Having access to this list on the Shortcuts app can enable them to do this.

I have created an Intent called "List All Unread Music Releases" and defined its response as a list of objects that contains information about each song. The problem is, when I go to the Shortcuts app, create a new shortcut using this Intent, and run it, it opens my app instead of running in the background.

Steps I've done to create and configure Intents

Here's a high level definition of what I did to configure Intents in the project. The next section will have the actual source code and screenshots.

  1. Created a new SiriKit Intent Definition File.
  2. Created a new Intent.
    • Defined it's Title, Description, Parameters, and disabled the "Intent is eligible for Siri Suggestions" checkbox.
    • Defined the response property as an Array (because it's going to be a list of songs), and configured the Output to be this array property.
  3. Created a new Intents Extension, with the checkbox "Include UI Extension" disabled. The idea here is to process the user request in the background and return a list with the results - no UI required.
  4. In the Intents Extension target, defined the IntentsSupported array inside Info.plist with the name of the intent created in step 2.
  5. Made the IntentHandler class implement the protocol generated for the intent created in step 2.

Code samples and screenshots

My SiriKit Intent Definition File and the GetUnreadReleases Intent:

在Xcode 11中,如何配置一个意图在后台运行?

The GetUnreadReleases Intent response:

在Xcode 11中,如何配置一个意图在后台运行?

The Intents Extension IntentHandler class:

import Intents

class IntentHandler: INExtension, GetUnreadReleasesIntentHandling {

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

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

    override func handler(for intent: INIntent) -&gt; 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
    }
    
}

The Intents Extension Info.plist file:

在Xcode 11中,如何配置一个意图在后台运行?

Conclusion

So, I would like this intent to run in the background, assemble the list of songs based on the user defined parameters, and return this list to be used as an input to other actions in the Shortcuts app.

It looks like previous versions of the Intents editor (Xcode < 11 / iOS < 13.0) had a checkbox "Supports background execution" that did just that, but I can't find it anymore on Xcode 11.

答案1

得分: 3

感谢来自苹果开发者论坛的edford,我能够让它正常工作。在意图定义文件中,必须选中“意图适用于Siri建议”复选框,以使后台执行正常工作。

英文:

Thanks to edford from Apple Developer Forums, I was able to make it work. In the intents definition file, the "Intent is eligible for Siri Suggestions" checkbox must be checked for the background execution to work.

huangapple
  • 本文由 发表于 2020年1月6日 20:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/59612316.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定