INIntent 属性 可以赋值 "Ask Each Time" 吗?

Can an INIntent property be given the value "Ask Each Time"?

假设我在 .intentdefinition 文件中定义了一个名为 FooIntent 的自定义意图。

它有一个类型为 Decimal 的参数 bar,其中:
- User can supply value in Siri and Shortcuts app 处于活动状态。
- Default Value0.

其自动生成的 class 定义现在如下所示:

public class FooIntent: INIntent {
    @NSManaged public var bar: NSNumber?
}

如果我构造一个FooIntent,将bar设置为nil,并将其传递给INUIAddVoiceShortcutViewController:

let intent = FooIntent()
intent.bar = nil
intent.suggestedInvocationPhrase = "Do foo"

let shortcut = INShortcut(intent: intent)

let viewController = INUIAddVoiceShortcutViewController(shortcut: shortcut!)
viewController.delegate = self
window?.rootViewController?.present(viewController, animated: true, completion: nil)

出现 Add to Siri 模态,bar 参数填充了 0,它的默认值。

如果在 Add to Siri UI 中,然后我将 bar 更改为 Ask Each Time 并按 Add to Siri,生成的委托方法调用会产生一个 INVoiceShortcut 对象,其中包含 barnil 值:

func addVoiceShortcutViewController(_ controller: INUIAddVoiceShortcutViewController, didFinishWith shortcut: INVoiceShortcut?, error: Error?) {
    if let intent = shortcut?.shortcut.intent as? FooIntent {
        print(intent.bar) // nil
    }
    controller.dismiss(animated: true, completion: nil)
}

如果我在UI中将bar设置为Clipboard也是如此。

如果我将它设置为一个值,例如42,然后 intent.bar 正确 returns 42.

既然nil好像代表一个参数的多个概念,那么Ask Each Time的概念存放在shortcut或intent objects中的哪里呢?

有什么我可以传递给 INUIAddVoiceShortcutViewController 的东西使得 intent.bar = <Ask Each Time>?

通常您可以在 IntentHanlder 中控制行为(是否继续要求用户输入特定参数)。例如,我是这样做的:

FooIntentHandler: NSObject, FooIntentHandling {

    func resolveBar(for intent: FooIntent, with completion: @escaping (FooBarResolutionResult) -> Void) {
        if let bar = intent.bar as? NSNumber {

            var everythingIsFine = false

            // Any logic here.
            // You can even assign an invalid magic number in your INUIAddVoiceShortcutViewController
            // so that your compare it here to see if the user has input anything different.

            if everythingIsFine {
                completion(FooBarResolutionResult.success(with: bar))
            } else {
                // With .needsValue() Siri will always ask for user input.
                completion(FooBarResolutionResult.needsValue())
            }
        } else {
            completion(FooBarResolutionResult.needsValue())
        }
    }
}

您也可以指定一个有效值作为初始值,在这种情况下,只要您在 resolve 方法中调用 FooBarResolutionResult.success(),Siri 就会接受参数值(无需用户输入),如上所示.

简而言之,Siri 调用这个 resolveBar() 来决定是否要求用户输入。