一个INIntent属性能否被赋值为“每次询问”?

5
假设我在.intentdefinition文件中定义了一个名为FooIntent的自定义意图。
它有一个单一参数bar,类型为Decimal,其中:
- 用户可以在Siri和Shortcuts应用程序中提供值已激活。
- 默认值为0。

它的自动生成的类定义现在如下所示:
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)

在“添加到Siri”模态框中,bar参数填充为默认值0

如果我在“添加到Siri”界面中更改bar为“每次询问”,并按下“添加到Siri”按钮,则生成的代理方法调用会产生一个包含barnil值的INVoiceShortcut对象:

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会正确返回42

由于nil似乎代表参数的多个概念,在捷径或意图对象中存储了Ask Each Time的概念吗?

我是否可以传递任何内容到INUIAddVoiceShortcutViewController,使得intent.bar = <Ask Each Time>

1个回答

1
通常在您的 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())
        }
    }
}

你也可以将一个有效值分配为初始值,在这种情况下,只要在你的解析方法中调用FooBarResolutionResult.success(),Siri 将接受 param 值(无需请求用户输入)。简而言之,Siri 调用此resolveBar()来决定是否请求用户输入。

我与苹果的一名工程师就此进行了通讯,他建议这个解决方案是旨在解决问题的。 - Naftali Beder

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