Быстрые команды Siri — как их реализовать?

Опубликовано: 2020-01-16

Ярлыки Siri, новая функция, представленная на прошлогодней конференции WWDC, позволяют выполнять определенные функции приложения в фоновом режиме. Нам не нужно включать приложение, чтобы использовать эти функции в приложении, мы можем просто сказать Siri, например, «Время бургера», и система узнает, какому приложению назначен этот ярлык, и закажет для нас бургер.

Что такое ярлыки Siri?

  • Удобный способ выполнять задачи с экрана блокировки или из области поиска.
  • В Siri также можно добавить ярлыки для запуска с голосовой фразой на iOS, HomePod и watchOS.
  • Разработчики добавляют в свои приложения ярлыки, которые позволяют Siri подключаться к этим ярлыкам.
  • Использование моделей машинного обучения вашего поведения для анализа общих функций, которые вы выполняете, и автоматического предложения ярлыков.
  • iOS 12+

В этой статье мы сосредоточимся на реализации ярлыка заказа, одного из самых популярных приложений Siri Shortcuts. Мы создадим простое приложение, которое позволит вам заказывать бургеры

Как мы можем создавать ярлыки Siri?

Процесс создания ярлыков Siri
  1. В самом начале мы должны подумать о функциональности, которую пользователь действительно хочет упростить в нашем приложении . Это должна быть функциональность, которую пользователь выполняет часто и требует от пользователя входа в приложение и прохождения в нем длинного пути. Ярлыки позволят сократить этот путь для выполнения функциональности.
  2. На следующем шаге вам нужно пожертвовать ярлык. Что это значит? Мы должны передать в систему информацию о том, что мы сделали заказ, например один бургер с беконом. Мы предоставляем эту информацию системе, и позже Siri может предложить нам в определенное время сделать этот конкретный заказ.
  3. Последнее, что нужно сделать, — это обработать этот ярлык, что происходит, когда пользователь говорит Siri команду, определенную ранее , например, «Время бургера», или в случае, когда пользователь нажимает ярлык, предложенный Siri, на экране блокировки.

Хорошо, может быть, мы напишем код? Каковы наши возможности как разработчиков?

NSUserActivity & Intents — примеры ярлыков Siri

NSUserActivity — мы создадим ярлык, который позволит нам запустить экран для создания нового заказа.

  1. Добавьте ключ в Info.plist
 <key>NSUserActivityTypes</key>
<массив>
	<string>com.miquido.SiriShotcutDemo.make-order</string>
</массив>

2. Пожертвовать ярлык, когда пользователь входит в экран

 пусть orderActivity = NSUserActivity (activityType: "com.miquido.SiriShotcutDemo.make-order")
orderActivity.persistentIdentifier = NSUserActivityPersistentIdentifier("com.miquido.SiriShotcutDemo.make-order")
orderActivity.isEligibleForSearch = истина
orderActivity.isEligibleForPrediction = истина
orderActivity.title = "Сделать заказ"
orderActivity.suggestedInvocationPhrase = "Время бургеров"

атрибуты let = CSSearchableItemAttributeSet (itemContentType: kUTTypeItem as String)
attribute.contentDescription = "Вкусные гамбургеры!"
attribute.thumbnailData = UIImage(название: «логотип»)?.pngData()
orderActivity.contentAttributeSet = атрибуты
активность пользователя = активность заказа

3. В AppDelegate вы должны реализовать делегат continueUserActivity , который после получения этого конкретного типа будет перенаправлять на данный экран

 func application(_ application: UIApplication,
                 продолжить userActivity: NSUserActivity,
                 restoreHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    если userActivity.activityType == "com.miquido.SiriShotcutDemo.make-order" {
        // обрабатывать открытое приложение на экране заказа
        вернуть истину
    } 
    вернуть ложь
} 
Процесс внедрения ярлыков Siri для заказа бургера

Намерения — Мы реализуем ярлык для выполнения заказов

Профессиональный совет перед внедрением:
Намерения появляются, когда пользователь делает что-то систематически. Однако, если вы хотите протестировать эту функцию, чтобы вы всегда получали предложение от Siri, вы должны включить две опции — « Отображать последние ярлыки » и « Отображать пожертвования на экране блокировки » в «Настройки» -> «Разработчик».

Параметры: Отображать последние ярлыки и Отображать пожертвования на экране блокировки.
  1. Создайте файл определения намерения. Лучше всего добавить его в отдельный фреймворк, в моем проекте он будет в OrderKit .
Значок файла определения намерения SiriKit

2. Выберите категорию, в данном случае «Заказ». В этом файле мы должны выбрать параметры, которые мы будем передавать в систему, и создать комбинации этих параметров.

Пользовательское намерение, параметры и типы ярлыков
Определение заказа — создание пользовательского намерения
Определение заказа — Задайте ответы
Определение заказа — Задайте ответы

3. Создайте новую цель с расширением для намерений, при создании выберите «Включить расширение пользовательского интерфейса».

Значок расширения намерений
Файл -> Создать -> Цель… -> Расширение намерений
Вот как должно выглядеть целевое членство для Order.intentdefinition

4. Создайте пользовательский интерфейс для намерения в файле MainInterface.storyboard .

Создание пользовательского интерфейса для намерения
Создание пользовательского интерфейса для нашего намерения

5. Настройте состояние ready и success в IntentViewController .

 func configureView(для параметров: Set<INParameter>,
                       взаимодействия: INInteraction,
                       интерактивное поведение: INUIInteractiveBehavior,
                       контекст: INUIHostedViewContext,
                       завершение: @escaping (Bool, Set<INParameter>, CGSize) -> Void) {
        
    охранять пусть намерение = взаимодействие.намерение как? OrderIntent еще {
        завершение (ложь, Set (), .zero)
        возвращаться
    }
    еслиinteraction.intentHandlingStatus == .ready {
        установка (с: намерение)
        waitTime.isHidden = истина
        завершение (истина, параметры, желаемый размер)
    } иначе, если взаимодействие.intentHandlingStatus == .success,
        пусть ответ = взаимодействие.интентОтвет как? ЗаказНамерениеОтвет {
        установка (с: намерение)
        waitTime.isHidden = ложь
        если позволить waitTimeText = response.waitTime {
            waitTime.text = "Заказ будет готов через \(waitTimeText) минут"
        }
        всеIsOkLabel.text = "Нажмите, чтобы показать заказы"
        завершение (истина, параметры, желаемый размер)
    }

    завершение (false, параметры, .zero)
}

настройка частной функции (с намерением: OrderIntent) {
    burgerNameLabel.text = намерение.burgerName
    если пусть количество = намерение.количество?.stringValue {
        количествоLabel.text = "\(количество) шт."
    }
    если позволить дополнения = намерение.дополнения {
        дополненияLabel.text = дополнения.элементы.toString
    }
}

6. После создания пользовательского интерфейса мы можем перейти к донату нашего намерения. В этом случае лучше всего пожертвовать намерения при оформлении заказа. Мы предоставляем в систему всю информацию, которую мы ранее определили в файле Order.intentdefinition , т.е. название бургера, количество и дополнения, а также предлагаемую фразу, отображаемую в том случае, когда мы хотели бы сразу добавить этот ярлык в Siri при оформлении заказа. .

 частная функция donateInteraction (для заказа: Заказ) {
    пусть взаимодействие = INInteraction (намерение: order.intent, ответ: ноль)
    
    взаимодействие.донат { (ошибка) в
        если ошибка != ноль {
            // обработка ошибки
        } еще {
            print("Успешно пожертвованное взаимодействие")
        }
    }
} 
 общественное расширение Заказать {
    
    переменная цель: OrderIntent {
        пусть orderIntent = OrderIntent()
        orderIntent.burgerName = имя
        если пусть intValue = Int(количество) {
            orderIntent.quantity = NSNumber (значение: intValue)
        }
        orderIntent.suggestedInvocationPhrase = "Время бургеров"
        
        orderIntent.additions = addions.map { option -> INObject in
            вернуть INObject (идентификатор: option.rawValue,
                            отображение: option.rawValue)
        }
        вернуть заказНамерение
    }
    
}

7. Теперь мы можем обработать ситуацию, что произойдет в случае, когда пользователь получит предложение ярлыка и нажмет на него, а также в случае, если пользователь вызовет ярлык с помощью Siri.

 открытый класс OrderIntentHandler: NSObject, OrderIntentHandling {
    
    общедоступная функция подтверждения (намерение: OrderIntent,
                        завершение: @escaping (OrderIntentResponse) -> Void) {
        завершение (OrderIntentResponse (код: OrderIntentResponseCode.ready, userActivity: nil))
    }
    
    общедоступный дескриптор функции (намерение: OrderIntent, 
                       завершение: @escaping (OrderIntentResponse) -> Void) {
        охранять let burgerName = намерение.burgerName else {
            завершение (OrderIntentResponse (код: .failure, userActivity: nil))
            возвращаться
        }
        
        Defaults.save (порядок: Порядок (от: намерение))
        завершение (OrderIntentResponse.success (burgerName: burgerName, waitTime: "5"))
    }
    
} 
Демонстрация быстрого доступа Siri

Вот и все, все работает

Вы можете проверить весь проект на моем GitHub здесь

Источники:

  • https://developer.apple.com/videos/play/wwdc2018/211/
  • https://developer.apple.com/videos/play/wwdc2018/214/
  • https://developer.apple.com/documentation/sirikit/donating_shortcuts
  • https://developer.apple.com/design/human-interface-guidelines/sirikit/overview/siri-shortcuts/
  • https://www.raywenderlich.com/6462-siri-shortcuts-tutorial-in-ios-12