«Давайте уволим половину разработчиков»: кроссплатформенная мобильная разработка в 2019 году

Никому не хочется делать работу дважды, и индустрия давно ищет способ разрабатывать для iOS и Android одно приложение вместо двух. До сих пор ни одна попытка реализовать это не становилась триумфальной, но в последнее время заявляют о себе три новых. Чем они отличаются, и может ли у них получиться лучше?

«Давайте уволим половину разработчиков»: кроссплатформенная мобильная разработка в 2019 году

Когда у компании есть приложения для iOS и Android, многие задачи при их разработке оказываются идентичными. Неудивительно, что возникает ощущение «у нас две команды разработчиков делают одно и то же, давайте как-то из двух кодовых баз сделаем одну, будет проще и дешевле». И давно появлялись различные решения для кроссплатформенной разработки, от PhoneGap до Xamarin.

Однако не всё так просто. Помимо идентичных задач, есть и платформозависимые, когда подходы на iOS и Android ощутимо различаются: работа с UI, обращение к hardware-компонентам вроде камеры или сенсоров, и так далее. В итоге благие намерения «давайте из двух кодовых баз сделаем одну» нередко заканчивались тем, что баз становилось три (общая, которая используется обеими платформами, и две специализированные). На трёх разных языках. Компании обнаруживали, что результат противоположен ожиданиям, и разочаровывались.

В последние годы главным претендентом на успех был фреймворк React Native от Facebook, и определённую нишу он действительно сумел занять. Но повсеместного распространения всё же не получил, а без разочарований не обошлось: в прошлом году нашумел пост Airbnb, которые после двух лет использования React Native отказались от него и вернулись к раздельной нативной разработке.

Несмотря на это, продолжают появляться новые решения. Какие именно и что заставляет их создателей считать, что вот в этот раз получится?

Flutter

«Давайте уволим половину разработчиков»: кроссплатформенная мобильная разработка в 2019 году

Разработка этого фреймворка началась ещё четыре года назад, а в 2017-м можно было услышать о том, что с его помощью сделали приложение мюзикла Hamilton. Но тогда всё это было на стадии эксперимента, а в декабре Flutter дошёл до версии 1.0, и теперь интерес в сообществе разработчиков такой, что появился даже русскоязычный Flutter-подкаст — в общем, настало время присмотреться всерьёз.

Flutter создан Google, что может звучать неожиданно. Эта компания стремится, чтобы нативная разработка Android-приложений была как можно удобнее. Зачем та же самая компания вкладывает ресурсы в альтернативный способ разработки, позволяющий делать приложения ещё и для конкурирующей платформы? Что вообще происходит?

Отчасти причина в том, что эта история не только про мобильные платформы: в перспективе Google хочет позволить запускать Flutter-приложения «везде, где можно отрисовывать пиксели», и уже начата работа над поддержкой десктопа и веба. А когда (и если) выйдет ОС Fuchsia, зреющая сейчас где-то в недрах Google, Flutter может стать основным способом разработки для неё.

Но это всё будущее, а что есть здесь и сейчас? Возможность писать кроссплатформенные мобильные приложения на языке Dart. Основным преимуществом, помимо переиспользования кода, Google называет функцию Hot Reload: если при нативной разработке, внеся изменения в код, придётся подождать, прежде чем увидишь их в запущенном приложении, то здесь они срабатывают почти моментально.

Это должно упрощать и ускорять разработку. Но про ускорение говорили и в случае с React Native, и это не сделало его популярнее нативной разработки. А в чём отличия, способные заставить кого-то выбрать Flutter?

Например, в подходе к UI. React Native использует нативные элементы интерфейса: если вы добавляете в проект кнопку, то в iOS-варианте приложения появится стандартная iOS-кнопка, и аналогично с Android-вариантом. Flutter решительно отказывается от этого: он не вызывает стандартные элементы ОС, а говорит «весь экран — мой холст, что хочу, то и рисую» (это стало возможным благодаря применению графического движка Skia, который уже давно используется в Google Chrome). И предлагает нарисовать что-нибудь такое, не привязанное к визуальному языку ни одной из платформ:

«Давайте уволим половину разработчиков»: кроссплатформенная мобильная разработка в 2019 году

Но если вы хотите «чтобы пользователю было привычно», это тоже не проблема: во Flutter встроен свой набор готовых UI-элементов, имитирующих привычные iOS/Android-элементы.

Помимо подхода к UI, на руку Flutter играет как раз тот факт, что он создан владельцами Android. Например, в качестве основной среды Flutter-разработки Google предлагает использовать свою Android Studio, которую Android-разработчики уже отлично знают. При этом строгого требования «только Android Studio» нет, у Flutter есть поддержка и в Visual Studio Code.

Есть и проблемные стороны. Одна из них в выборе Dart. Во-первых, этот язык не используют ни в iOS, ни в Android. Во-вторых, его вообще мало где используют: если React Native помогало обилие JavaScript-разработчиков в мире, то опытного Dart-разработчика найти затруднительно. Но попробовавшие Dart дружно говорят, что освоить его после Java или другого ОО-языка несложно, так что принципиального барьера здесь нет.

Другая проблема — в репутации Google как компании, часто убивающей собственные проекты. Поэтому даже после релиза Flutter 1.0 у многих осталось настороженное отношение: «Что будет, если мы перепишем всё на Flutter, а потом Google его забросит?»

Ну и, наконец, Flutter не совершает чуда: хотя в случае с UI и избавились от привязки к платформе, в ряде других задач эта привязка остаётся. Так что полностью абстрагироваться от платформы не получится, при разработке по-прежнему потребуются знания и по iOS, и по Android. А в части случаев по-прежнему будут получаться три кодовые базы на трёх разных языках. В общем, помочь Flutter может, но ожидать «всё упростится ровно вдвое» не стоит.

Kotlin multiplatform

«Давайте уволим половину разработчиков»: кроссплатформенная мобильная разработка в 2019 году

Язык Kotlin уже стал стандартом в Android-разработке, приложения массово переходят с Java на него. Но Android дело не ограничивается: создавшая Kotlin компания JetBrains работает и над поддержкой самых разных платформ, и над удобством переиспользования Kotlin-кода между платформами. Один из предлагаемых вариантов такого переиспользования — как раз между Android и iOS.

У JetBrains есть важное отличие от многих других сторонников кроссплатформенности: там изначально не ставят целью «чтобы была одна полностью универсальная кодовая база». Пока кто-то стремится к этому идеалу и обжигает крылья, в этом случае сразу признают, что радикальный подход «всё общее» работает плохо, и даже не пытаются его воплотить.

Вместо этого предлагают переиспользовать только по-настоящему общую часть кода, где разработчики на разных платформах действительно пишут одно и то же. А всё различающееся по-прежнему писать нативно. И пока Flutter сосредоточен на полном объединении UI, здесь его, наоборот, никак не объединяют.

Грубо говоря, всё общее предлагают выделить в библиотеку на Kotlin, подходящую сразу для iOS и Android, а дальше обращаться к этой библиотеке с обеих сторон. Так что с Kotlin Multiplatform мобильный проект заведомо получается из трёх составляющих — общей и двух раздельных. И тут напрашивается возражение: «Подождите, мы оказывались недовольны, если из двух кодовых баз получалось три, а нам предлагают сразу же именно так и сделать. В чём тогда смысл вообще?»

Но здесь играет важную роль популярность Kotlin в Android-разработке. Если в других случаях «три кодовых базы» означает «на трёх разных языках», то здесь не требуется притаскивать в свой мобильный проект новый язык: зачастую он там и так уже есть. А в команде уже есть люди, умеющие на нём хорошо писать. Вот iOS-разработчикам придётся сталкиваться с новым для них языком, но им упрощает жизнь сходство Kotlin со Swift и интероперабельность со Swift/Objective-C. Любопытно, как это всё скажется на ролях в команде: границы платформ размываются и появляется «общая» часть, но она не одинаково близка обеим сторонам.

Выбрав подход «проект из трёх частей», JetBrains направили усилия на максимально бесшовное взаимодействие этих частей: идея совмещения «общего» и «платформозависимого» кода тут поддержана прямо на уровне языка. Когда одна и та же функция должна быть реализована по-разному на разных платформах, в «общем» коде её объявляют со специальным ключевым словом expect («такая функция в принципе есть, можно её вызывать»), а в «раздельном» с ключевым словом actual пишут две конкретные реализации этой функции. На скриншоте выше виден пример общего кода, функция platformName() действует по-разному в зависимости от того, на каком смартфоне она запущена.

Конечно, абсолютной бесшовности всё равно не достичь, и сложных вопросов на стыке разных миров остаётся много. Насколько успешно получится решить их у JetBrains — пока что открытый вопрос: если Flutter уже перешагнул через ключевую отметку «версия 1.0», то мультиплатформенные возможности Kotlin пока что снабжены значком «experimental», всё на более ранней стадии. И пока что нет примера большого приложения с Kotlin multiplatform (но можно посмотреть на код маленького).

Слово «экспериментальный» обычно означает, что тащить технологию в рабочий проект пока рано. Но также оно означает стадию, когда на неё можно ощутимо лично повлиять: многие важные решения всё ещё не отлиты в граните, и на них сказывается фидбек. Так что, если опробуете мультиплатформенность Kotlin применительно конкретно к своим задачам, столкнётесь с проблемой и сообщите о ней JetBrains — сейчас выше вероятность, что всё изменится в удобную вам сторону.

PWA

«Давайте уволим половину разработчиков»: кроссплатформенная мобильная разработка в 2019 году

В этом месте со стороны читателей могут полететь помидоры. Во-первых, если текст о разработке мобильных приложений, то при чём тут сайты? Во-вторых, как можно считать их «новым подходом» в 2019-м, если понятию PWA (Progressive Web Apps) далеко не один год, а Стив Джобс и вовсе предлагал использовать веб-приложения ещё при запуске первого айфона?

Действительно предлагал, но есть нюанс: веб-приложения в 2007-м и в 2019-м — это совсем не одно и то же. И буквально за последний год появились новые возможности, с которыми стоит ещё раз посмотреть на PWA и понять, не пора ли теперь считать их полноценными кроссплатформенными приложениями.

В чём исходная идея PWA? «Конечно, с сайтами удобно, что избегаешь всей этой тягомотины с дублированием iOS/Android, но нативные приложения в чём-то выигрывают. Например, они могут работать в офлайне и присылать уведомления, а их красивая иконка на домашнем экране и в App Store так и манит юзера тапнуть. Так давайте дадим сайтам все возможности приложений, и всё станет прекрасно!»

Процесс «дадим эти возможности» тогда действительно пошёл, но неторопливо. Хотя за идею PWA ратует Google, похоже, что внутри компании идёт холодная война между командами Chrome и Android: в Chrome хотят поскорее дать Android-пользователям все возможности PWA, но у Android-команды свои приоритеты вроде Instant Apps. А Apple вообще годами игнорировала это явление, не поддерживая возможности PWA на iOS, словно Джобс никогда не агитировал в пользу ничего подобного.

Но год назад тихо произошёл тектонический сдвиг: начиная с версии iOS 11.3, в Safari появилась поддержка ключевых PWA-технологий. При этом Apple настолько не высказывается об этом публично, что даже не сообщила об этих изменениях в списке нововведений iOS 11.3. И когда пользователь откроет ваш PWA-сайт, айфон не станет обращать его внимание «это веб-приложение можно добавить на домашний экран», как делает Android. Получается странная полуофициальная поддержка, при которой преимущества PWA могут пройти мимо заинтересованных людей. Но главное — лёд тронулся, теперь можно говорить о кроссплатформенности.

А вот другое событие, произошедшее меньше двух месяцев назад: в Chrome 72 для Android появилась поддержка Trusted Web Activity, и это шаг в направлении «публикация PWA в Google Play» (пока там всё непросто, но в будущем может стать проще). Зачем вообще веб-приложению публиковаться в магазине, если сайт и так доступен по ссылке? Потому что магазины остаются мощным источником аудитории, пользователи открывают их, когда хотят установить что-то.

Наконец, совсем свежая новость: поддержка PWA появилась в Chrome на macOS, и поскольку она уже была в Chrome на Windows и Linux, теперь десктопный сегмент охвачен целиком. Хотя это и не относится напрямую к мобильной разработке, для кого-то эта новость станет аргументом в пользу отказа от нативного подхода: «лучше сделаю сайт, который где угодно можно установить как программу, на любой телефон и любой компьютер».

В общем, сейчас создание PWA привлекательнее, чем когда-либо. Но при этом остаётся и миллион различных неудобств. Например, на iOS PWA-сервисы могут получать от камеры отдельные снимки, но не могут получать видеопоток (это портит жизнь, например, QR-сканерам). А на Android, если пользователь поменял телефон, система охотно восстановит установленные им на предыдущий нативные приложения — но не восстановит добавленные им на домашний экран PWA.

В итоге PWA технически уже можно назвать «приложениями, которые устанавливаются и на Android, и на iOS», а практически остаётся большим вопросом, насколько оправдано их использование вместо обычных приложений — но вероятно, что в будущем их поддержка продолжит улучшаться.

Что в итоге? Тем, кому хочется «уволить половину мобильных разработчиков», 2019-й не поможет: ни один из трёх описанных подходов не позволяет просто взять и реализовать всё универсально. Но вот тем, кому интересен любой возможный прирост эффективности (пусть и далеко не в два раза), стоит обратить внимание на все три.

Когда вариантов расплодилось так много, какую технологию выбрать для вашего нового приложения? Ответ скучный, но от того не менее истинный: у каждой свои преимущества и свои риски, и лучше, чтобы в команде был человек, способный принять взвешенное решение. Сможем ли мы реализовать всё, что нам нужно, в PWA? Будет ли скорость работы нашей команды максимальной с React Native? Возникнут ли проблемы с нативными фичами во Flutter? Есть ли у нас вообще люди со знаниями Kotlin/Swift? Ответы на все эти вопросы важны.

Если «лучшего» кроссплатформенного подхода не существует, то какой хотя бы станет самым популярным? Пока что невозможно сказать и это — но похоливарить в комментариях всё равно может быть весело.

А если вместо холиваров вы хотите закопаться в тему глубже — мы проводим конференцию Mobius, там в декабре было по докладу про Flutter и мультиплатформенный Kotlin, и из них можно узнать больше технических подробностей:

А на следующем Mobius, который состоится в Петербурге в мае, будет ещё один доклад о мультиплатформенном Kotlin — в этот раз с акцентом на то, что изменилось в версии Kotlin 1.3.

40
39 комментариев