Вступление
С тех пор как Siri была представлена еще в 2011 году, разработчики iOS просили предоставить ей возможность интегрировать сторонние приложения. С выпуском iOS 10 во время WWDC 2016 Apple наконец-то сделала SiriKit доступной для разработчиков. Есть все еще некоторые ограничения на то, какие типы приложений могут использовать преимущества Siri, но это шаг в правильном направлении. Давайте посмотрим, что мы можем сделать с Сири.
Чтобы узнать больше о SiriKit и других новых функциях для разработчиков под iOS 10, ознакомьтесь с курсом Маркуса Мюльбергера, прямо здесь, на Envato Tuts +.
Поддерживаемые Домены
Чтобы использовать SiriKit, ваше приложение должно находиться в одном или нескольких из следующих доменов:
- VoIP звонки (например, Skype)
- Обмен сообщениями (WhatsApp)
- Платежи (Квадрат, PayPal)
- Фото (Фото)
- Тренировки (Runtastic)
- Бронирование поездки (Uber, Lyft)
- CarPlay (только для автомобильных поставщиков)
- Бронирование ресторанов (требуется дополнительная поддержка от Apple)
Если ваше приложение не относится ни к одной из этих категорий, к сожалению, вы не можете использовать Siri в своем приложении в данный момент. Не уходите пока, хотя, потому что SiriKit очень мощный, и он может получить новые возможности в будущем!
Архитектура расширения
Расширение SiriKit в действительности состоит из двух типов расширений. Требуется расширение Intents
которое заботится о том, чтобы обрабатывать запросы пользователя и выполнять определенную задачу в вашем приложении (например, начать вызов, отправить сообщение и т. Д.).
С другой стороны, расширение IntentsUI
не является обязательным. Вы должны создать только один, если вы хотите настроить пользовательский интерфейс, который Siri показывает при представлении ваших данных. Если вы этого не сделаете, отобразится стандартный интерфейс Siri. В этом уроке мы рассмотрим оба типа расширений.
К вашему сведению, во время WWDC 2016 Apple выпустила два очень интересных видео о SiriKit. Вы можете проверить их:
Пример проекта
Мы собираемся создать простое приложение, которое обрабатывает платежи через Siri. Цель состоит в том, чтобы успешно обработать предложение «Отправьте 20 долларов Патрику через TutsplusPayments». Формат предложения состоит из суммы денег с определенной валютой, имени получателя и приложения, которое будет использоваться для завершения транзакции. Позже мы собираемся проанализировать способ оплаты более подробно.
Начальная настройка
Давайте начнем с создания стандартного проекта Xcode в Swift и присвоения ему имени. Перед написанием любого кода необходимо выполнить несколько обязательных шагов, чтобы ваше приложение могло использовать API-интерфейсы Siri.
1. Выберите пункт Tar > Capabilities и включите функцию Siri. Убедитесь, что права были успешно созданы в структуре вашего проекта.
2. Откройте Info.plist
вашего приложения и добавьте ключ NSSiriUsageDescription
. Значение должно быть строкой, объясняющей использование Siri, которая будет показана пользователю при запросе начального разрешения.
3. Выберите « Файл»> «Создать»> «Цель» . В новом окне, представленном XCode, под Расширениями приложения выберите Расширение Intents . Также выберите вариант для включения расширения пользовательского интерфейса. Это избавит вас от необходимости создавать другое отдельное расширение.
В файле Info.plist
вновь созданной цели Intents
полностью разверните словарь NSExtension
чтобы изучить его содержимое. Словарь описывает более подробно, какие намерения поддерживает ваше расширение, и хотите ли вы разрешить пользователю вызывать намерение, пока устройство заблокировано.
Вставьте наиболее релевантные намерения вверху, если вы хотите поддержать более одного. Siri использует этот порядок, чтобы выяснить, какой пользователь хочет использовать в случае неоднозначности.
Теперь нам нужно определить, какие намерения мы хотим поддержать. В этом примере мы собираемся создать расширение, которое поддерживает способ оплаты. Измените файл Info.plist
чтобы он соответствовал следующей картинке.
Здесь мы указываем, что мы хотим обработать INSendPaymentIntent
и что мы требуем, чтобы устройство было разблокировано. Мы не хотим, чтобы посторонние отправляли платежи, когда устройство потеряно или украдено!
iOS Target
Следующим шагом фактически является написание некоторого кода в приложении для iOS. Мы должны запросить у пользователя разрешение отправить свой голос в Apple для анализа. Нам просто нужно импортировать инфраструктуру Intents
и вызвать соответствующий метод следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
import UIKit
import Intents
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Ask permission to access Siri
INPreferences.requestSiriAuthorization { authorizationStatus in
switch authorizationStatus {
case .authorized:
print(«Authorized»)
default:
print(«Not Authorized»)
}
}
}
}
|
Результирующий диалог, представленный пользователю во время первого запуска приложения, будет выглядеть следующим образом.
Это все, что мы должны сделать в нашем простом приложении для iOS. Давайте войдем в мир расширений сейчас!
Расширение намерений
Переключитесь на расширение Intents
которое мы создали ранее. Раскройте его содержимое в навигаторе проекта Xcode. Вы увидите только один файл с именем IntentHandler.swift
.
Этот файл является точкой входа вашего расширения и используется для обработки любых намерений, которые отправляет вам Siri. Siri отправит handler(for:)
метод все намерения, если ваше расширение поддерживает несколько типов. Ваша задача — проверить тип объекта INIntent
и правильно его обработать.
Шаблон IntentHandler.swift
уже содержит пример реализации намерения обмена сообщениями. Замените весь код следующим пустым методом, чтобы мы могли вместе пройти каждый шаг.
1
2
3
4
5
6
7
8
|
class IntentHandler: INExtension {
override func handler(for intent: INIntent) -> Any?
// This is the default implementation.
// you can override this and return the handler you want for that particular intent.
return self
}
}
|
Каждое намерение имеет связанный протокол, чтобы убедиться, что класс реализует все необходимые методы. Большинство протоколов в структуре Intents имеют одинаковую структуру.
Протокол, который мы собираемся реализовать, называется INSendPaymentIntentHandling
. Этот протокол содержит следующие обязательные и необязательные методы:
- Необходимые:
handle(sendPayment:completion:)
- Необязательный:
confirm(sendPayment:completion:)
resolvePayee(forSendPayment:with:)
resolveCurrencyAmount(forSendPayment:with:)
resolveNote(forSendPayment:with:)
Давайте создадим расширение класса IntentHandler
в том же файле Swift для реализации единственного необходимого метода.
01
02
03
04
05
06
07
08
09
10
11
12
|
extension IntentHandler: INSendPaymentIntentHandling {
func handle(sendPayment intent: INSendPaymentIntent, completion: @escaping (INSendPaymentIntentResponse) -> Void) {
// Check that we have valid values for payee and currencyAmount
guard let payee = intent.payee, let amount = intent.currencyAmount else {
return completion(INSendPaymentIntentResponse(code: .unspecified, userActivity: nil))
}
// Make your payment!
print(«Sending \(amount) payment to \(payee)!»)
completion(INSendPaymentIntentResponse(code: .success, userActivity: nil))
}
}
|
Это очень простая реализация. Мы уверены, что есть действующий payee
и currencyAmount
чтобы сделать транзакцию успешной. Вы можете не верить этому, но это уже работает! Выберите схему Intents из Xcode и запустите ее. Когда Xcode представляет обычное меню для выбора приложения для запуска, выберите Siri.
Когда Siri запускается, попробуйте сказать: «Отправьте Патрику 20 долларов через TutsplusPayments». Теперь наслаждайтесь первым успешным платежом, совершенным с вашим голосом
Вы также можете попробовать проверить неисправность. Попробуйте произнести то же предложение, что и раньше, но без указания получателя (т. Е. «Отправить 20 долларов через TutsplusPayments»). Вы увидите, что Siri потерпит неудачу и представит пользователю кнопку для продолжения платежа в вашем приложении.
В случае, если Siri не понимает или не имеет ни одного из необязательных параметров, но вам требуется допустимое значение, вы можете реализовать один из методов разрешения. Эти методы предоставляют пользователю возможность предоставить более подробную информацию о платеже, такую как имя получателя, точную сумму в валюте и даже примечание. Благодаря этой интеллектуальной архитектуре API вам, как разработчику, предоставляется возможность легко и четко понимать запросы вашего пользователя по-разному.
В реальном приложении вы создадите динамическую среду, которая будет использоваться совместно вашим приложением iOS и расширениями. Используя эту архитектуру, вы можете использовать одну и ту же бизнес-логику в нескольких целях. Вам не нужно будет реализовывать это несколько раз, но только один раз и для всех целей!
Расширение Intents UI
В последней части этого руководства я покажу вам, как вы можете настроить пользовательский интерфейс, отображаемый Siri.
Прежде всего, не забудьте установить правильный класс намерений, который вы хотите обрабатывать в Info.plist
ExtensionUI
, как мы делали в предыдущем разделе.
Перейдите в расширение Intents UI, и вы увидите шаблон, который Xcode создал для вас. Он содержит IntentViewController
, который является простым подклассом UIViewController
который реализует протокол INUIHostedViewControlling
. Файл раскадровки был также создан для вас; откройте его, чтобы мы могли начать настройку пользовательского интерфейса.
Добавьте UIImageView
в качестве фона и метку в центре. Загрузите фоновое изображение , импортируйте его в целевой объект Intents и установите как изображение вновь созданного UIImageView
. Создайте объект UILabel
и UILabel
его в центр представления. Вы можете легко использовать AutoLayout
чтобы установить ограничения в раскадровке.
Откройте помощник редактора и создайте @IBOutlet
для своей метки и назовите его contentLabel
. Результат должен выглядеть примерно так:
Откройте файл IntentViewController
и вы увидите несколько примеров кода. Вы можете удалить все, кроме configure(with:context:completion:)
метода configure(with:context:completion:)
который мы собираемся реализовать сейчас. Этот метод вызывается, когда пользовательский интерфейс готов к настройке. Здесь мы должны установить содержимое UILabel
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
class IntentViewController: UIViewController, INUIHostedViewControlling {
@IBOutlet weak var contentLabel: UILabel!
// MARK: — INUIHostedViewControlling
func configure(with interaction: INInteraction!, context: INUIHostedViewContext, completion: ((CGSize) -> Void)!) {
if let paymentIntent = interaction.intent as?
// If any of this properties is not set, use the default UI.
guard let amount = paymentIntent.currencyAmount?.amount, let currency = paymentIntent.currencyAmount?.currencyCode, let name = paymentIntent.payee?.displayName else {
return completion(CGSize.zero)
}
let paymentDescription = «\(amount)\(currency) to \(name)»
contentLabel.text = paymentDescription
}
if let completion = completion {
completion(self.desiredSize)
}
}
var desiredSize: CGSize {
return self.extensionContext!.hostedViewMaximumAllowedSize
}
}
|
Прежде всего, мы проверяем, что объект intent
имеет тип INSendPaymentIntent
. Если это так, мы также гарантируем, что все свойства, которые мы хотим отобразить, не равны nil
, в противном случае мы просто вызываем блок завершения с нулевым размером, чтобы скрыть наше пользовательское представление. Если все идет так, как мы ожидаем, мы создаем пользовательскую строку с данными, которые мы хотим показать пользователю, и устанавливаем ее как текст contentLabel
.
Запустите расширение снова, и вы увидите новый вид внутри Siri!
Сири по-прежнему показывает вид по умолчанию. Мы можем скрыть это, заставив наш контроллер представления соответствовать протоколу INUIHostedViewSiriProviding
.
1
2
3
4
5
6
|
class IntentViewController: UIViewController, INUIHostedViewControlling, INUIHostedViewSiriProviding {
// Previous code goes here…
var displaysPaymentTransaction: Bool {
return true
}
}
|
Возвращая значение true
в переменную displayPaymentTransaction, мы сообщаем Siri, что наш контроллер представления заботится о отображении всей необходимой информации пользователю и что представление по умолчанию может быть скрыто. Результат теперь намного чище!
Примечание. Как видно на этом рисунке, при указании валюты, отличной от долларов США, Siri правильно понимает и возвращает код валюты в расширение. К сожалению, текст всегда отображает доллары США. Я сообщил об этой ошибке в Apple!
Вывод
Я надеюсь, вам понравился этот урок. В настоящее время Siri очень мощная, даже если она ограничена некоторыми типами приложений. Если вы планируете использовать его в своих собственных приложениях, убедитесь, что вы хорошо продаете его своим пользователям, потому что они могут не знать, насколько крутым и продвинутым стало ваше приложение!
Если вы хотите узнать больше об интеграции Siri в свое приложение или если вы хотите узнать о некоторых других интересных функциях iOS 10 для разработчиков, ознакомьтесь с курсом Маркуса Мюльбергера.
Кроме того, ознакомьтесь с некоторыми другими нашими бесплатными руководствами по функциям iOS 10.