Можно ли присвоить свойству INIntent значение «Спрашивать каждый раз»?

Допустим, я определил пользовательское намерение, называемое FooIntent, в файле .intentdefinition.

Он имеет единственный параметр bar типа Decimal, для которого:
- User can supply value in Siri and Shortcuts app активен.
- Default Value равен 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)

появится модальное окно Add to Siri с параметром bar, заполненным 0, его значением по умолчанию.

Если в Add to Siri пользовательском интерфейсе я затем изменю bar на Ask Each Time и нажму Add to Siri, результирующий вызов метода делегата создаст объект INVoiceShortcut, содержащий значение nil для bar:

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)
}

То же самое верно, если я установил bar на Clipboard в пользовательском интерфейсе.

Если я установил для него значение, например 42, тогда intent.bar правильно возвращает 42.

Поскольку nil, похоже, представляет несколько концепций для параметра, где концепция Ask Each Time хранится в ярлыках или объектах намерений?

Могу ли я передать в INUIAddVoiceShortcutViewController что-нибудь такое, что intent.bar = <Ask Each Time>?


person Naftali Beder    schedule 19.10.2019    source источник


Ответы (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())
        }
    }
}

Вы также можете назначить допустимое значение в качестве начального, и в этом случае Siri примет значение параметра (без запроса ввода пользователя), пока вы вызываете FooBarResolutionResult.success() в своем методе разрешения, как показано выше.

Короче говоря, Siri называет это resolveBar(), чтобы решить, запрашивать ли ввод пользователя.

person Wei WANG    schedule 05.12.2019
comment
Я переписывался с инженером Apple по этому поводу, и он предположил, что это решение является предполагаемым. - person Naftali Beder; 08.01.2020