Найти тему
IceRock Broadcasts

Kotlin Multiplatform for Mobile Development: когда стандартная нативная разработка уходит в историю

Самая острая проблема

За последние годы программирование развивается семимильными шагами. Технологии разработки, которые еще недавно считались современными и даже перспективными, уже сейчас сменяются более новыми и уходят в историю. Несмотря на этот постоянно работающий двигатель прогресса и частые изменения и усовершенствования, вопрос сокращения издержек на разработку приложений остается открытым. Тем не менее, ребята из JetBrains совершили невероятную попытку оптимизации трудозатрат при создании мобильных приложений. А именно, они взялись за стоявшую уже достаточно давно проблему переиспользования уже написанного кода, которая до сих пор остается актуальной, причём не только в пределах одной платформы, но и между разными. Мы заведем речь об основных мобильных платформах об основных мобильных платформах - iOS и Android.

Почему эта проблема достаточно остро стояла в последнее время? Возможность переиспользования кода способна существенно ускорить и оптимизировать процесс написания любого приложения, особенно по сравнению с популярной сейчас нативной разработкой приложения, которая хотя и считается одной из наиболее удобных, проверенных и доступных технологий для компаний-разработчиков, тем не менее не подразумевает переиспользование кода даже в теории. В этом случае приложения получаются полностью независимыми друг от друга с отдельной кодовой базой для iOS и для Android. Получение правки на одной платформе совсем не означает, что на другой платформе эта правка априори будет сделана быстрее.

Пути решения

Если рассмотреть поднятую проблему, то можно выделить два основных пункта: использование одного и того же кода на обеих платформах и непосредственно само переиспользование. Одно из препятствий для использования единого кода: разные языки программирования, на которых пишутся приложения для платформ. Для Android это Java и Kotlin, а для iOS используются ObjectiveC и Swift - совершенно ничего общего, и просто просто взять один и тот же код и преподнести его компилятору для другой платформы не получится. Однако, сегодня разработчик может это препятствие преодолеть, причем несколькими путями:

  • Xamarin
  • React Native
  • J2ObjC
  • Kotlin/Native

Каждый из способов имеет собственные недостатки и преимущества. Xamarin и React Native добавляют дополнительную абстракцию от платформ. Они усложняют работу с самой платформой и не дают использовать обширный набор библиотек от нативного iOS/Android-сообщества. В случае с Xamarin появляется зависимость от разработчиков платформы, и поддержку новых версий iOS/Android должны выпустить именно они. React Native же пишется на языке JavaScript, при этом теряется производительность, а сам язык программирования открывает много возможностей для ошибок (не типобезопасный и некомпилируемый). Старый гугловский инструмент J2ObjC не предоставляет возможности использовать функционал iOS-платформы из Java.

Последнее решение, Kotlin/Native, лишено подобных недостатков, в связи с чем имеет заметные преимущества перед остальными, кроме того сам язык Kotlin по сравнению с Java гораздо более краткий и лаконичный язык, а код, написанный на нем, проще и компактнее, чем выполняющий ту же задачу код, написанный на Java.

Мы пришли к выводу, что для использования одного и того же кода на обеих платформах, Android и iOS, наиболее удобная технология на данный момент - это Kotlin/Native. Однако вопрос, достаточно ли этого, чтобы успешно переиспользовать код остается открытым. На данном этапе приходится сталкиваться с ещё одним препятствием: разное API разных платформ. Это значит, что даже несмотря на то, что код написан один, всё равно придётся писать еще и дополнительный код под разные платформы, пусть и на едином языке, Kotlin. В таком случае приходится делать дополнительную работу, а в итоге мы получаем:

1) исходный common-код, в котором сам код не обращается к платформенным

библиотекам и является одинаковым и на Android, и на iOS;

2) iOS-Platform-код, в котором делаются обращения к платформенным библиотекам iOS (например, запросы к серверу);

3) Android-Platform код, в котором также делаются обращения к android-фреймворку: (те же запросы к серверу).

Т.е. получается, что для работы общего кода нужно, чтобы при компиляции под Android дополнительно был и код Android-Platform, а при компиляции под iOS соответствующий iOS-Platform-код. Причина заключается в том, что сам по себе common-код неполноценен и не может решить даже простейшую и наиболее популярную задачу мобильных приложений: отправить запрос на сервер, а контролировать вручную эти процессы достаточно трудоемко. Команда JetBrains смогла предположить подобную проблему и предусмотрела её решение, поэтому помимо добавления Kotlin на различные платформы, была предоставлена и возможность создания мультиплатформенных проектов.

За счет специальной конфигурации проекта теперь есть возможность сделать проект, который будет компилироваться в Android-библиотеку со специфичным кодом именно для Android, а в iOS-фреймворк с соответствующим кодом для iOS. В итоге получается, что с технической точки зрения, проблем для использования одного кода на iOS и Android одновременно больше нет. При отладке кода его нужно будет править лишь один раз, и исправления произойдут сразу на обеих платформах. Однако на нативной стороне приложений остается то, что и не обобщить без потери качества, а именно:

- Весь интерфейс;

- Привязка интерфейса к общим viewmodel из библиотеки общего кода;

- Платформозависимые фичи: работа с камерой, NFC, Touch ID или Bluetooth.

Преимущества по сравнению с Native

Конечно нельзя сказать, что у продукта JetBrains совсем нет никаких недостатков. Например стоит отметить, что уже большое количество разработчиков используют нативный способ разработки и наработали на нем сравнительно немало опыта, т.е. скорее всего компании не потребуется выделять дополнительные накладные расходы на обучение разработчика новой технологии, чего, к сожалению, нельзя сказать о Kotlin/Native, когда определенные образовательные расходы вполне вероятны. Также при чисто нативной разработке можно использовать любой из множества уже проверенных архитектурных подходов, учитывающих конкретную платформу, можно использовать большое количество нативных библиотек без какой-либо дополнительной работы. В то время как в случае с Kotlin/Native при желании использовать нативную библиотеку в общем коде необходимо будет прибегнуть к Expect/Actual реализации.

Тем не менее, несмотря на пока ещё слабое распространение среди нынешних разработчиков и некоторые проблемы, присущие всем новым технологиям, Kotlin Multiplatform вместе с Kotlin/Native по сути универсализирует разработку на Android и iOS, что, самое главное, помогает уменьшить общее количество ресурсов, необходимых для программирования приложения на обе платформы, при этом не снижая планку качества разработки. Таким образом компания, внедрившая в работу эти технологии, получает дополнительную экономию в бюджете, что в свою очередь также снижает стоимость разработки для клиента. При использовании Kotlin/Native, разработчику скорее всего даже не будет требоваться дополнительная работа для правки при отладке кода на одной из платформ, что заметно уменьшает трудозатратность подобной работы.

Что касается обучения, то на опыте нашей команды мы можем привести пример, когда iOS-разработчик, впервые столкнувшись с Kotlin, за неделю освоился в Multiplatform-проекте и сейчас успешно поддерживает и пишет новый общий код в common-библиотеке. К слову, использование Kotlin multiplatform будет быстрее даваться Android-разработчикам, но в целом сама технология не является слишком сложной для обучения на уже существующем проекте. А именно, если разработчик еще не знаком с Kotlin Multiplatform и Kotlin/Native, но должен поддерживать проект, созданный с ее помощью, то образовательные расходы на него не будут значительны.

Kotlin/Native существенно снижает трудозатраты на разработку приложений
Kotlin/Native существенно снижает трудозатраты на разработку приложений

И всё-таки почему Kotlin/Native?

Следует подытожить ключевые преимущества Kotlin/Native и Kotlin Multiplatform по сравнению с текущей разработкой, а именно:

- Для работы над проектом не требуется по отдельному выделенному специалисту на каждую платформу: один из специалистов может делать общий код и нативную сторону его платформы, позже на очень короткое время потребуется подключение специалиста с другой платформы, для реализации своей нативной стороны, не реализуя, однако, повторно всё то же, что делал первый специалист;

- Сам код пишется лишь единожды, затем компилируется под другую платформу, это избавляет разработку от получения разных реализаций под разные платформы и от появления разных багов между платформами: поведение их обеих будет унифицировано и изменяться будут обе вместе;

- Поддержка и развитие приложения становится экономичнее, эффективнее, реализация различных фич также проходит заметно быстрее (и даже вдвое быстрее) за счет использования одной и той же кодовой базы и усилий одного и того же разработчика.

На KotlinConf 2018 в начале октября было объявлено, что Kotlin/Native перешел в статус beta-тестирования, а компания JetBrains в данный момент делает акцент на реализации инструментария для разработки Kotlin Multiplatform iOS- и Android-проектов. Вместе с релизом Kotlin 1.3 ожидается и релиз Kotlin/Native 1.0. Команда IceRock Development уже успешно использует Kotlin Multiplatform проект под iOS и Android в разработке и намерена и далее активно развивать это направление.