Apple показала на WWDC 2016 новые iOS 10 и macOS Sierra, и я не упустил возможность сразу же обновить свои устройста.
Одно из ключевых обновлений — появление SiriKit для разработчиков, теперь у нас с вами есть возможность использовать Siri в собственных приложениях. И мы сегодня сделаем наше первое приложение с поддержкой Siri (исходники проекта в конце статьи)
(!) Уважаемые читатели «Хабрахабра», все ошибки и правки по данной статье присылайте, пожалуйста, в личные сообщения.
Мои впечатления от iOS 10 и macOS
В новой macOS появилась Siri — это сразу бросается в глаза, с новыми функциями. Наконец-то заработал обмен ссылками между iOS и macOS — как только открываешь страницу на iPhone/iPad — сразу появляется на mac значек Safari, открывающий эту страницу (Раньше эта функция работала через раз). Ну и конечно очень круто — что копируя текст на iOS — его можно вставить на macOS. С картинками и фото тоже самое — один клик на iPhone, и фото уже на ноутбуке, больше не нужно мэйлить фото самому себе. По умолчанию включается на macOS телеметрия, которую я сразу отключил (скрин). Из минусов iOS 10 — действительно тормозная, иногда (не всегда) на iPhone 5S и iPad Air подтормаживает скролл, но в целом, интерфейс выглядит более стильно, контрастнее, изменения UI незначительные, но в целом «более стильно и минималистично» :) В плане UI дизайна так же стоит отметить обновленные формочки для IN-APP уведомлений.
(!) Если кто-то поставил iOS 10, то чтобы в старом xcode (7.3) можно было работать с девайсом, нужно просто из xcode 8.0 в xcode 7.3 скопировать папку «DeviceSupport/10.0» в тоже место.
Из каталога:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/10.0 (14A5261u)/
В папку:
Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/10.0 (14A5261u)/
Apple предлагает несколько сценариев для использования Siri сторонними разработчиками:
- Аудио и видео звонки
- Работа с сообщениями и контактами
- Совершение платежей с помощью Siri
- Поиск фотографий
- Тренировки
- Работа с картами (Вызов такси)
В данной статье я покажу, как создавать StoryBoard интерфейс для Siri и вызывать наши функции с помощью голосового помощника.
Для начала скачиваем и устанавливаем Xcode 8 и создаем новое приложение с одним ViewController и называем его, например «DemoApp».
Для добавления голосовой поддержки нам придется добавить новое расширение, для этого выбираем в левой панели файлового менеджера верхнюю строчку (файл проекта) и выбираем в меню Editor -> Add target…
Назовем наше расширение «DemoAppSiriIntent», так же не забываем проверить наличие галочки напротив «Include UI Extension»
Так же для работы Siri нам необходимо добавить в проект библиотеку CoreLocation.framework
У нас в проекте появились новые файлы
- IntentHandler.m — файл с CallBack функциями, которые возвращает Siri
- IntentViewController.m — файл для работы с StoryBoard интерфейсом, который расположен рядом, в файле MainInterface.storyboard
Для начала мы научим наше приложение запускать «Фитнес активность» (Workout), для этого в файле IntentHandler.m должны быть объявленны следущие Delegates:
@interface IntentHandler () <INStartWorkoutIntentHandling, INPauseWorkoutIntentHandling, INResumeWorkoutIntentHandling, INCancelWorkoutIntentHandling, INEndWorkoutIntentHandling>
@end
Для обозначения методов взаимодействия с Siri Apple использует слово «Intent», теперь, зажимая клавишу CMD, кликаем на «INStartWorkoutIntentHandling» и смотрим, какие функции использует данный deligate.
Обязательный для включения в проект метод:
- handleStartWorkout
Дополнительные методы, которые можно не включать в проект:
- confirmStartWorkout
- resolveWorkoutNameForStartWorkout
- resolveGoalValueForStartWorkout
- resolveWorkoutGoalUnitTypeForStartWorkout
- resolveWorkoutLocationTypeForStartWorkout
- resolveIsOpenEndedForStartWorkout
Медод «confirmStartWorkout» вызывает по порядку следущие Callback функции, которые уже автоматически созданы в нашем файле «IntentHandler.m»:
- resolveWorkoutNameForStartWorkout
- resolveGoalValueForStartWorkout
- DemoAppSiriIntent
- resolveWorkoutLocationTypeForStartWorkout
- resolveIsOpenEndedForStartWorkout
- confirmStartWorkout
- handleStartWorkout
Рядом с файлом «IntentHandler.m» мы видим plist с настройками нашего «Intent» расширения, «Info.plist».
Проверяем, что в ветке "NSExtension -> NSExtensionAttributes -> IntentsSupported" перечислены все наши Intents для работы с Siri Workout:
- Item 0: INStartWorkoutIntent
- Item 1: INPauseWorkoutIntent
- Item 2: INResumeWorkoutIntent
- Item 3: INCancelWorkoutIntent
- Item 4: INEndWorkoutIntent
Если мы продублируем данные «Intents» в ветку "NSExtension -> NSExtensionAttributes -> IntentsRestrictedWhileLocked", то Siri сможет вызывать функции из нашего приложения даже с заблокированного устройства.
Теперь переходим к файлу «MainInterface.storyboard» и для демо приложения добавляем на него два UILabel, один из них будет счетчиком, для демонстрации того, что наш UI интерфейс внутри Siri может обновляться в реальном времени.
Важно отметить, что данный интерфейс не может содержать «gesture recognizers» и перехватчики событий нажатия пальцами и, при закрытии данного окна, Siri освободит все объекты в памяти.
На следующей схеме мы можем ознакомиться с жизненным циклом нашего «Siri view интерфейса».
Итак, самое время скомпилировать наше приложение и проверить, работают ли голосовые команды. Тестировать данный пример получится только на реальном устройстве, для начала собираем приложение как обычно:
Затем нажимаем на Stop и отдельно компилируем наше расширение, выбрав схему «DemoAppSiriIntent». Во время компиляции Xcode спросит нас, для какого приложения мы собираем данное расширение, и в списке мы указываем «DemoApp».
На этом этапе мы увидим, что наше приложение появляется на секунду и тут же исчезает, это не «вылет», всё функции вывода NSLog из файла «IntentHandler.m» показывают нам, что все работает.
Ах да, чуть не зыбыл, в настройках нашего iOS девайса заходим в раздел Siri и устанавливаем галочку напротив нашей программы «DemoApp»:
Итак, самое время произнести вслух «Hey, Siri, start workout in DemoApp»
Результат вы можете наблюдать на данном видео:
Теперь мы убедились, что все работает, давайте добавим поддержку сообщений в наше приложение.
Перейдя по данной ссылке, вы можете ознакомиться со всеми «Intent» методами, которые поддерживаются в данный момент Siri:
https://developer.apple.com/...
Сейчас нас интересует секция «Messaging», открываем наш «IntentHandler.m» файл, прописываем delegate для сообщений:
@interface IntentHandler () <INSendMessageIntentHandling>
Удерживая зажатой CMD — кликаем на «INSendMessageIntentHandling» и видим, что необходимой функцией в этот раз является «handleSendMessage». Для начала присваиваем «Intent» для сообщений в функции «handlerForIntent»:
- (id)handlerForIntent:(INIntent *)intent {
id handler = nil;
if ([intent isKindOfClass:[INSendMessageIntent class]]) {
handler = self;
}
handler = self;
return handler;
}
И затем пишем callback функцию для нашего «Intent»:
- (void)handleSendMessage:(INSendMessageIntent *)intent completion:(void (^)(INSendMessageIntentResponse * _Nonnull))completion {
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INSendMessageIntent class])];
INSendMessageIntentResponse *response = [[INSendMessageIntentResponse alloc] initWithCode:
INSendMessageIntentResponseCodeSuccess userActivity:userActivity];
NSLog(@"handleSendMessage");
completion(response);
}
Не забываем прописать наш новый «Intent» в plist.info, в ветку "NSExtension -> NSExtensionAttributes -> IntentsSupported":
Вот и все, данную статью я написал в очень сжатые строки, но если вам интересна данная тема, дайте знать в комментариях, я могу написать более расширенную публикацию, включающую такие нюансы, как локализация команд Siri в нашем приложении, работа с картами, составление синонимов для голосовых фраз и обучающие фразы для Siri, ну и конечно же проблемы бета версии Xcode 8.
Исходные файлы проекта из данной статьи вы можете скачать по ссылке:
http://big-lab.com/images/articles/sirikit/DemoApp.zip
Комментарии (17)
InstaRobot
15.06.2016 10:25+1Спасибо. Достаточно шустро материал по новым фичам появился. Скажите, в Вы ставили сиерру также? Стабовский икскод нормально с симуляторами работает?
У меня тоже азарт появился, я сразу заапдейтился на рабочую машину + телефон + часы + приставка. Но только забыл за основное правило, что ставить все превьюшное добро следует на специальное железо для тестов. Как итог, сломанный икскод + невозможно нормально собрать рабочий проект + битый код по фреймвокам в личном проекте (с последним коммитом аж несколько дней назад).
Ну а так, фишек действительно много добавлено, нужно теперь все это добро разобрать за короткое время. Будем разбирать, но теперь только на дублирующей системе.
Не думали еще, как все покрыть тестами?megabraza
15.06.2016 11:09+1Да, macOS Sierra я тоже поставил. Традиционно перестали работать мои любимые CleanMyMac и HandsOff (Фаервол), но надеюсь в ближайшее время мне удастся их обновить.Что касается Xcode 8 beta — симуляторы работают, так же в Xcode немного изменился шрифт (особенно заметно на знаках препинания).
Из того, что мне не понравилось (остальным возможно понравится) — в Xcode 8 переработали панель инструментов позиционирования (скрин), больше нет универсальной формы для всех девайсов — под каждый девайс отдельные настройки отступов. Кнопка «Clear Constaints» у меня перестала работать вовсе, никакой реакции, пришлось удалять «Constaints» вручную по одной из левого списка с иерархией форм. Перезагрузка не помогла. Буду разбираться.
Но Xcode 7.3 (стабильный) у меня остался, так что нет причин переживать за невозможность собрать рабочий проект.
house2008
15.06.2016 16:16+3Привет. Тоже хочу поставить сиеру на выходных, но боюсь, что AppCode сломается, так как это моя основная среда разработки. Вы не проверяли, работает ли эта IDE нормально на новой системе? Спасибо.
ps.
Если кто-то поставил ios 10, то чтобы в старом xcode (7.3) можно было работать с девайсом, нужно просто из xcode 8.0 скопировать в него папку в тоже место. Сообщаю просто так, вдруг кто не знает.
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/10.0 (14A5261u)
InstaRobot
15.06.2016 19:04+1Занятно, не знал об этой фишке! Попробую обязательно, но теперь на другой машине
InstaRobot
15.06.2016 19:05+1Так тут наверное из-за первой беты в основном. Нужно ждать фиксов в следующей версии.
InstaRobot
15.06.2016 19:22+1P.S.: Ах да, сразу забыл написать, проверьте обновление 'CleanMyMac', еще рано утром вышла бета у них с поддержкой сиерры! Ребята молодцы, быстро реагируют на новинки. Ни разу не пожалел, что софт у них покупаю)
megabraza
15.06.2016 11:31Среди новых команд к Siri вычитал такую «Насколько мощный мой компьютер». Попробовал… Видимо Siri видала железо помощнее моего Mac Pro :)
bezhangadoev
15.06.2016 11:54+1установил вчера iOS10 beta на iPhone 6 голос Siri пропал. У Вас так же? И кто знает как это исправить?
megabraza
15.06.2016 11:58+1Попробуй перезагрузить iPhone, вдруг поможет (лично у меня разовая перезагрузка Mac и iPhone устранила несколько UI багов)
firya
15.06.2016 12:40Насколько я понял сири сможет отправлять сообщения в тех же мессенджерах, а зачитывать она их сможет? Было бы здорово, особенно если бы она не теряла контекст
Akisame
17.06.2016 10:04Я не iOS разработчик, но с интересом слежу за развитием платформы.
Мне, как бэкенд разработчику, предоставляемое API кажется довольно странным… Т.е. услышав анонс того что Siri открыли разработчикам, я ожидал совсем другого API (более декларативного и гибкого). А в итоге есть 5-6 ограниченных сценариев и привкус разочарования. Может просто я привык к тому что API должно покрывать как частные случаи, так и позволять более гибко работать с обобщенным сценарием.
Какого ваше (iOS разработчиков) мнение насчет предоставленного API? Как много реальных use case-ов оно покрывает?megabraza
17.06.2016 10:21+1Я ждал, что API Siri позволит распознавать любую речь внутри моего приложения, но получил возможность вставить кусочек моего приложения в Siri. На данный момент я пользуюсь только двумя сценариями Siri, которые выглядят примерно так:
- Установи будильник на 7 утра
- Напомни о конференции в четверг в 15-30
Новое API добавляет с моей точки зрения только один полезный use case — «Вызови UBER/Яндекс.такси», и думаю именно для этих компаний оно и полезно.
Не думаю, что кто-то будет активно пользоваться «Siri, отправить деньги», ведь это может быть и так:
— Siri, отправь триста долларов моему брату
— Окей, я отправляю три тысячи сто долларов в Apple.Akisame
17.06.2016 10:39Примерно того же ожидал и я.
Я думал что можно будет декларативно описать какой контекст вызывает мое приложение и какие команды в нем доступны.
Например в моем приложении можно управлять роботом. Я ожидал что можно будет попросить Siri «передай Дэниелю <расследуй преступление>». А так максимум что я могу его попросить, это поставить будильник…
Для меня это API пока на уровне «все равно лучше, чем ничего». Я понимаю что они взяли пару популярных use case-ов и позволили их запускать через Siri, но если они таким образом делают основу, то боюсь API нормального развития не получит.
Нужно посмотреть как это организованно в Amazon Echo. Быстрый поиск показал что Google Now позволяет похожим образом вызывать пару частных команд (по крайней мере сейчас).
NickSin
Спасибо за статью. Если можно, то я был бы рад прочитать расширенную версию.