Обсудить проект

Опыт разработки кроссплатформенного мобильного приложения с помощью трех различных инструментов: Embarcadero Delphi, Xamarin, Flutter.

Оглавление

Введение
Реализованное приложение
Описание инструментов разработки
Пользовательский интерфейс
Работа с базой данных и сетью
Платформозависимый функционал
Достоинства и недостатки
Заключение
Ссылки

Введение

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

Реализованное приложение

Приложение представляет собой инструмент оценки и сравнения характеристик автомобиля, таких как дизайн, безопасность, комфорт и др.

Пользователь имеет возможность вводить технические параметры своего автомобиля или нескольких автомобилей.

Для каждого автомобиля пользователь может оценить набор его характеристик и сравнить эти оценки с усредненными оценками других пользователей.

Для сохранения и получения усредненных оценок используется серверное приложение, доступ к которому осуществляется через Web API. Оценки пользователя также хранятся локально в базе данных.

Приложение позволяет авторизоваться, зарегистрировать нового пользователя и управлять настройками.

Ниже приведены изображения основных экранов приложения.

Главное окно. В карусели содержится список автомобилей пользователя. 
Ввод технических параметров автомобиля.

Оценка характеристик автомобиля. Каждая пиктограмма соответствует одной из характеристик. Перемещая пиктограмму по горизонтали, мы меняем оценку от «плохо» до «хорошо». А перемещая по вертикали, от «неважное» до «важное».

Усредненные оценки других пользователей (пиктограммы черного цвета). Также можно показать/скрыть свои оценки для сравнения (пиктограммы синего цвета).

Описание инструментов разработки

Delphi

Интегрированная кроссплатформенная среда разработки Embarcadero RAD Studio 10.4.2 позволяет создавать приложения для ОС Windows, OS X, Apple iOS и Android, используя единую кодовую базу на языках Delphi или C++. В проекте использовался язык Delphi. Компиляторы Delphi на основе LLVM позволяют получать «нативный» код для каждой ОС.

Пользовательский интерфейс приложения разрабатывался с помощью библиотеки FMX, входящей в состав RAD Studio.

Для развертывания и удаленной отладки приложения на мобильных устройствах Apple (для тестирования использовались iPhone и iPad с iOS 15.0) применялась интегрированная среда разработки Xcode 12.5, установленная на macOS 11 Big Sur. Для связи RAD Studio c macOS был установлен PAServer (Platform Assistant Server Application).

Xamarin

Xamarin — это платформа с открытым исходным кодом на языке C#, предназначенная для разработки приложений для iOS, Android, tvOS, watchOS, macOS и Windows с .NET. Платформа Xamarin представляет собой уровень абстракции, который обеспечивает управление взаимодействием между общим кодом и кодом базовой платформы. Xamarin выполняется в управляемой среде, которая реализует такие возможности, как выделение памяти и сборка мусора.

Пользовательский интерфейс приложения разрабатывался с помощью платформы Xamarin.Forms 5.0.

Для создания кода использовалась интегрированная среда разработки Microsoft Visual Studio 2022.

Для развертывания и удаленной отладки приложения на мобильных устройствах Apple (для тестирования использовались iPhone и iPad с iOS 15.0) применялась интегрированная среда разработки Xcode 13.2, установленная на macOS Monterey.

Flutter

Flutter — комплект средств разработки и фреймворк с открытым исходным кодом для создания мобильных приложений под Android и iOS, веб-приложений, а также настольных приложений под Windows, macOS и Linux с использованием языка программирования Dart, разработанный и развиваемый корпорацией Google.

Пользовательский интерфейс приложения разрабатывается с помощью Widget-ов. Widget-это отдельный структурный элемент приложения написанный на языке Dart.

В Flutter есть базовый набор компонентов для использования и возможность загрузки необходимых компонентов в отдельных модулях (пакетах).

Для написания кода использовалась интегрированная среда разработки IntelliJ IDEA.

Пользовательский интерфейс

Delphi

Для создания макета пользовательского интерфейса в среде Embarcadero RAD Studio используется визуальный конструктор форм. Размеры, позиционирование, внешний вид, обработчики событий и другие свойства элементов управления можно устанавливать в окне свойств этого элемента. Размеры и положение элементов на форме можно также менять помощью мыши.

Для построения пользовательского интерфейса был выбран паттерн Model-View-Presenter (MVP).

В проекте использовались стандартные элементы управления, без установки дополнительных библиотек. Для каждого типа элемента был разработан собственный стиль FMX. Подробнее о стилях будет рассказано далее.

Xamarin

Для создания макета пользовательского интерфейса в Xamarin.Forms используется язык разметки приложений eXtensible Application Markup Language (XAML) — язык на основе XML, созданный Microsoft. Он позволяет задавать структуру, планировку и стиль элементов управления, а кроме того в нем поддерживается привязка к данным и возможность обработки событий.

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

В Xamarin.Forms нет визуального конструктора представлений пользовательского интерфейса. Вместо этого используется горячая перезагрузка XAML. Работает она так:

  • вы запускаете свое приложение на устройстве или на эмуляторе;
  • вносите изменение в разметку XAML;
  • наблюдаете на экране устройства или эмулятора результат ваших изменений.

Так как Xamarin.Foms и XAML изначально ориентированы на применение паттерна Model-View-ViewModel (MVVM), то этот паттерн и был выбран авторами статьи для построения архитектуры приложения.

В проекте использовались стандартные элементы управления, без установки дополнительных библиотек. Кроме того, на основе стандартных элементов управления, были разработаны собственные: карусель, панель заголовка, тулбар, пиктограмма автомобиля.

Flutter

Для построения пользовательского интерфейса в Flutter используется язык Dart.

Каждый отдельный элемент пользовательского интерфейса представляет собой Widget, структурный элемент приложения который затем отрисовывается на экране.

Код Dart компилируется в native код использующий для отрисовки Skia. Flutter также встраивает собственную копию Skia как часть движка, позволяя разработчику обновлять свое приложение, даже если на телефоне не установлена новая версия Android.

То же самое верно и для Flutter на других платформах, таких как iOS, Windows или macOS.

В Flutter так же как в Xamarin нет визуального конструктора представлений пользовательского интерфейса. И для удобства разработки есть возможность «горячей перезагрузки», которая работает аналогично:

  • вы запускаете свое приложение на устройстве или на эмуляторе;
  • вносите изменение в код Dart Widget-ов;
  • наблюдаете на экране устройства или эмулятора результат ваших изменений.

Для реализации проекта на Flutter, помимо стандартных элементов управления так же устанавливались дополнительные модули для локализации, работы с БД и сетью, отдельные элементы управления.

Работа с базой данных и сетью

Принципиальных различий в работе с компонентами приложения, не связанными с пользовательским интерфейсом, в рассматриваемых инструментах нет. В любой платформе есть провайдер доступа к данным, ORM и компоненты для работы с сетью. Эти компоненты или входят в стандартную поставку или являются бесплатными сторонними библиотеками. Компоненты, использовавшиеся в данных проектах, приведены в таблице ниже. Во всех трех проектах для хранения данных использовалась БД SQLite.

  Delphi Xamarin Flutter
Провайдер базы данных FireDAC (стандартная библиотека) Microsoft.Data.Sqlite (стандартная библиотека) sqflite
ORM EntityDAC Express Edition 3.0.2 sqlite-net-pcl 1.8 sqflite
Http клиент REST Client Framework (стандартная библиотека) System.Net.Http(стандартная библиотека) http 0.13.4

Платформозависимый функционал

Кроссплатформенные инструменты разработки не позволяют в общем коде пользоваться всем спектром возможностей конкретных платформ. В первую очередь это относится к дизайну и к возможностям пользовательских устройств (доступ приложения к контактам, камере, данным GPS и т. п.).

Посмотрим, как осуществляется организация платформозависимого кода в рассматриваемых инструментах.

Embarcadero Delphi

В Delphi задача выполнения нужного кода решается с помощью условной компиляции в зависимости от платформы.

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

Xamarin

Приложения Xamarin.Forms обычно состоят из общей библиотеки .NET Standard и проектов отдельных платформ. Общая библиотека содержит представления XAML или C# и всю бизнес-логику. Проекты платформы содержат всю зависящую от платформы логику или пакеты, необходимые приложению.

В проектах платформы можно подключить классы, поддерживаемые конкретной мобильной платформой, которые находятся в библиотеках C# для Xamarin.Android и Xamarin.iOS соответственно. Таким образом мы можем использовать весь набор возможностей этих платформ.

В общем проекте также можно определить платформозависимый код или значений свойств в XAML с помощью класса OnPlatform.

Flutter

В Flutter есть API для определения платформы в которой запускается приложение, однако встроенных инструментов для работы, например, с камерой или галереей нет.

Для работы с платформозависимым функционалом требуется установка дополнительных плагинов.

Достоинства и недостатки

Delphi

Достоинства

Стили FMX
Если вы в своем приложении хотите использовать элементы управления, внешний вид которых должен отличаться от стандартного, то вам может облегчить задачу использование стилей компонентов. Основное предназначение стилей компонентов — разработка богатых кастомных пользовательских интерфейсов

Библиотека FMX позволяет для каждого элемента управления и для каждого типа элемента управления создавать свой стиль. Стиль FMX — это контейнер, содержащий набор объектов, которые могут быть скрыты от разработчика и определяют внешний вид и поведение компонента. Применение стилей позволяет не создавать новые элементы управления на основе имеющихся, а просто выбирать для каждого элемента свой стиль. Например, у нас есть на форме две группы кнопок, имеющих разный внешний вид (размер, цвет и т.п.) и различное поведение при взаимодействии с пользователем (нажатие, наведение мыши и т.п.). Достаточно создать 2 собственных стиля и указать нужный для каждой кнопки, не создавая при этом никаких дополнительных классов элементов управления. Преимущество такого подхода состоит в уменьшении объема исходного кода. Стили могут применяться как в конструкторе форм на этапе разработки, так и «на лету» в процессе выполнения программы.

Недостатки

Модель приложения
Главным недостатком использования Delphi FMX авторы статьи считают несоответствие модели приложения FMX и модели реального мобильного приложения на Android или iOS. Многие элементы управления, которыми оперирует Delphi, пришли туда из Windows, вместе со своими наборами свойств и событий. Например, TreeView, ListView, ToolBar, StatusBar и т. п. Эти и другие элементы управления реализуются библиотекой FMX на мобильных платформах либо как набор «нативных» платформенных компонентов, либо полностью используют свой рендеринг. Отсюда возникают сложности в использовании свойств и событий «нативных» платформенных компонентов. Следствием этого является также различное поведение элементов управления FMX на разных платформах.

Этот недостаток ярко иллюстрируется ограниченной возможностью использования жестов в FMX. На данный момент в нем «жестко» зашит определенный набор жестов, и у разработчика нет доступа к низкоуровневому управлению жестами для «точной» настройки.

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

Xamarin

Достоинства

Ориентирование Xamarin.Foms на паттерн MVVM.
Все больше разработчиков Android и iOS переходят на использование этого паттерна в своей архитектуре. Kotlin, язык программирования для разработки приложений Android, имеет встроенную поддержку MVVM. На Swift, языке для разработки iOS и OS X приложений, написаны библиотеки, позволяющие применять этот паттерн. Авторы статьи ни в коем случае не утверждают, что другие паттерны MVx чем-то хуже. Они лишь хотят обозначить, что переход на MVVM в архитектуре мобильных приложений становится тенденцией.

Декларативное описание интерфейса.
Использование языка XAML позволяет использовать декларативный подход для разработки пользовательского интерфейса. Этот подход используется и в Android, где структура пользовательского интерфейса хранится в XML. Apple также выпустила фреймворк SwiftUI, позволяющий использовать декларативный подход для создания интерфейса.

Декларативное описание интерфейса нагляднее показывает его структуру; позволяет без перекомпиляции менять планировку; помогает адаптироваться к различным платформам, размерам экрана и соотношениям его сторон. Как правило, один экран мобильного приложения содержит гораздо меньше элементов, чем экран настольного приложения. Поэтому декларативное описание кажется более наглядным и удобным для модификации. Использование такого подхода, на наш взгляд, предпочтительней, чем использование гибридного подхода, который применяется в Delphi.

Кроме того, при необходимости, в Xamarin можно использовать и императивный подход, создавая и меняя структуру и свойства элементов интерфейса программно.

Недостатки

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

Также некоторые сбои наблюдались и в работе со списком выбора в элементе управления Picker.

Flutter

Достоинства

Прозрачность кода
Язык Dart и сама экосистема Flutter устроена таким образом, что разработчик вынужден придерживаться определенного, достаточно узкого паттерна проектирования. Что позволяет обеспечить высокую читаемость и достаточно легкое понимание кода. Кто бы ни разрабатывал приложение, код будет организован таким образом, какой требуется во Flutter. В отличие от C# например, где существует огромная свобода архитектуры, и зачастую это приводит к излишнему усложнению приложений и сложности в понимании.

Активный пакетный менеджер
У Flutter активное сообщество и удобный пакетный менеджер, в котором можно найти и подключить множество решений для различных целей, будь то кастомизированные компоненты или инструменты для работы с БД, сетью, внутренними функциями.

Подключение пакетов производится путем добавления названия в файл спецификации пакетов, далее они загружаются в проект с помощью IDE.

Сообщество
На текущий момент Flutter является относительно молодым и активно развивающимся инструментом (первый выпуск в 2017). И получил большую популярность среди сообщества мобильных разработчиков сообщества, благодаря чему находить ответы и решения тех или иных проблем относительно просто. В сравнении например с Delphi, где решение приходится с трудом искать либо в тех. поддержке, либо в старых темах (10 лет и более).

Недостатки

Примитивность языка Dart
В отличие от других языков таких как Java, C# или Delphi в Dart достаточно сложно реализовывать необходимую логику и структуру приложения. Реализация одной и той же логики может потребовать написания гораздо большего количества кода на Dart по сравнению с другими упомянутыми языками. Например, методы работы с коллекциями или анонимными функциями, generic-и или методы расширения. При переходе с более «богатого» языка на Dart это будет сильно ощущаться.

Производительность
Платформа Flutter вынуждает проектировать UI таким образом, что на любое изменение в приложении, будь то передача новых значений, обработка нажатий кнопок или жестов, требуется вызов изменения состояния Widget-ов. Что в свою очередь вызывает постоянную перерисовку UI, и контроль над этим переложен на плечи разработчика, в отличие от того же Delphi или Xamarin, где этот функционал «скрыт» от разработчика и контролируется платформой автоматически.

Сравнительная таблица

Сравним рассмотренные нами инструменты еще по некоторым характеристикам, важным для выбора платформы разработки.

  Delphi Xamarin Flutter
Затраты на разработку приложения 3 чел/месяца 1 чел/месяц 1.5 чел/месяц
Доступ к функционалу конкретной платформы (Android или iOS) Cложный. Нужно самим портировать в Delphi большую часть API платформ Простой. Весь API платформ портирован в соответствующие библиотеки на C# Средний. Для доступа к различным API платформы требуется установка дополнительных модулей(пакетов) 
Задержка обновлений для последних версий Android и iOS 5 месяцев 1-2 месяца 1-2 месяца
Порог вхождения Низкий, для разработчика, знакомого с Delphi Низкий, для разработчика, знакомого с C# и .NET Средний, для разработчика мобильных приложений
Наличие специалистов (по данным HH.ru) 127 1646 3273

Заключение

С учетом всех достоинств и недостатков рассмотренных инструментов можно сделать вывод, что Xamarin отражает специфику разработки мобильных приложений намного больше, чем Delphi или Flutter. В Xamarin используются те подходы, которые используют разработчики Android и iOS, такие как паттерн MVVM и декларативное описание интерфейса. Кроме того, разработчик Xamarin может легко задействовать «нативный» функционал конкретной платформы, в то время как на Flutter и, тем более, Delphi это сделать сложнее.

Производительность всех рассматриваемых платформ невысокая по сравнению с «нативной». По этой причине их будет нецелесообразно использовать для создания комплексной анимации, игр и высоконагруженных приложений. Для создания таких приложений лучше подойдут инструменты, предоставляемые разработчиками платформ, такие как Kotlin для Android и Swift для iOS.

У всех инструментов есть задержка обновлений для последних версий Android и iOS. Но Delphi реагирует заметно медленнее на появление новых версий.

Порог вхождения в Xamarin и FMX минимальный для разработчика, знакомого соответственно с C# или Delphi. Порог вхождения в Flutter также небольшой, однако для реализации более продуманной архитектуры или более сложного приложения потребуется значительно больше времени потратить на глубокое понимание платформы и того, каким образом подходить к реализации того или иного проекта.

Специалистов, предлагающих себя в качестве разработчика FMX гораздо меньше, чем специалистов Xamarin и Flutter. Но, так как Flutter относительно новая платформа, то и специалисты в ней сейчас не имеют обширного опыта разработки. Это безусловно нужно учитывать при выборе той или иной технологии для реализации.

Ссылки