Знакомство с Watch App

Не так давно мне поручили изучение WatchKit и реализацию MVP для Apple Watch. Я с влажными от волнения ладошками побежал пробовать то, чем я раньше не занимался. Если кратко, то задача состояла в отображении сгенерированного в виде картинки QR-кода на часах.

Мною был найден неплохой цикл статей на Medium, посвященных разработке под WatchOS, где поэтапно рассматривался весь процесс. Только вот я столкнулся с некоторыми сложностями, о которых там не говорилось или упоминалось вскользь.

Первой неожиданность для меня стало то, что Watch OS не поддерживает UIKit, в ней реализован свой WatchKit, где есть похожие элементы, но с сильно ограниченной функциональностью, поэтому часто приходилось использовать следующее:

#if os(iOS)
    //Insert UIKit (iOS) code here
#elseif os(watchOS)
    //Insert WatchKit (watchOS) code here
#endif

Далее я задумался над тем, как же приложение будет обмениваться данными между Apple Watch и iPhone. Для этого существуют разные способы, такие как App Group, шаринг файлов, баз данных и прочее.

В главном приложении в качестве базы данных была выбрана Realm и я подумал: наверняка есть решение, которое позволит шарить базу данных и синхронизировать данные. Немного поискав я нашел целый туториал на эту тему, но позже, хорошо все обдумав, я решил использовать WatchConnectivity, специальный фреймворк предназначенный для обмена данными между Apple Watch и iPhone, где данные передаются как словарик.

Так как Core Image, с помощью которого можно генерировать QR, был недоступен на watchOS, а найденная на GitHub JS-библиотека, которая помогала генерировать QR на watchOS, дико лагала, я решил генерировать QR на телефоне и передавать на часы.

На этом шаге я столкнулся с новыми трудностями: я преобразовал массив полученных QR в pngData и складывал в словарик, но при обмене данными получал ошибку - PayloadTooLarge. Проблема в том, что согласно документации Apple, максимальный размер передаваемого словаря составляет 65.5 kB. Для решения этой задачи мне пришлось сильно уменьшить разрешение сгенерированных QR.

При добавлении Watch App к вашему основному проекту создается target вашего приложения для watchOS c идентификатором {идентификатор основного приложения}.watchkit и расширение к нему с идентификатором {идентификатор основного приложения}.watchkitapp.watchkitextension.

Проблемы у вас появятся тогда, когда вы решите загрузить свое приложение, которое поддерживает Apple Watch в TestFlight, чтобы протестировать все. (К слову, Fabric не поддерживает работу с Apple Watch) При загрузке вам будет показана ошибка, в которой будет сказано, что данный application id не подходит и вам нужно использовать другой…. Apple, за что!? Причем ни в одном туториале об этом не сказано.

Ответ был найден знаете где? Конечно же на Stackoverflow, где же еще.

Если кратко - вместо .watchkitapp. пишем .watchkit., а вместо .watchkitextension пишем .extension.

Я загрузил приложение в TestFlight и начал дожидаться завершения обработки, наивно полагал, что все проблемы остались позади, но я ошибался. На почту пришло письмо с бла-бла-бла … Missing Info.plist value - A value for the Info.plist key CFBundleIconName is missing in the bundle ‘’ … бла бла бла.

В общем, да, я забыл добавить иконки для приложения на watchOS. Я так хотел уже потыкать свое приложение в проде, а тут иконки… В итоге, я даже не стал дожидаться дизайнера, по-быстрому сгенерировал иконки с помощью сервиса и отправил приложение повторно.

И да, на этот раз все прошло успешно.

Вот таким было мое первое знакомство в WatchKit. Возможно мой опыт сможет кому-нибудь сэкономить пару часов жизни.

Written on September 23, 2019