Чем отличается Xamarin.Forms от Xamarin.Native?

Xamarin.Forms и Xamarin.Native (под которым обычно понимаются Xamarin.iOS и Xamarin.Android) — это два подхода к созданию мобильных приложений с помощью платформы Xamarin. Оба позволяют разрабатывать приложения на языке C# с использованием .NET, но различаются в уровне доступа к платформенным возможностям и способе построения пользовательского интерфейса.

Основные отличия: краткое определение

  • Xamarin.Forms — это кроссплатформенный UI-фреймворк, позволяющий создавать единый пользовательский интерфейс для Android, iOS (и раньше — UWP), используя общий XAML-код и C#-логику.

  • Xamarin.Native (Xamarin.iOS и Xamarin.Android) — это тонкие обёртки над нативными SDK iOS и Android, позволяющие писать платформозависный код, но на C#. Интерфейс создаётся отдельно под каждую платформу, в соответствии с её рекомендациями.

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

Xamarin.Forms:

  • Используется XAML (расширяемый язык разметки) для описания интерфейса.

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

  • Пример: Button в XAML превращается в UIButton на iOS и Button на Android.

  • Поддерживает механизм data binding и MVVM-архитектуру по умолчанию.

Xamarin.Native:

  • Интерфейс создаётся отдельно для каждой платформы — с помощью Storyboard/XIB/SwiftUI-аналога на iOS (в Xamarin.iOS) и XML-макетов или программного кода на Android (в Xamarin.Android).

  • Доступ ко всем нативным виджетам, фреймворкам и шаблонам интерфейса.

  • Можно использовать любые дизайнерские и UX-паттерны, предусмотренные ОС.

Доступ к функциональности и API

Xamarin.Forms:

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

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

Xamarin.Native:

  • Полный и прямой доступ к платформенным API.

  • Например, в Xamarin.iOS можно работать с CoreAnimation, ARKit, HealthKit и другими iOS-фреймворками без ограничений.

  • Аналогично, Xamarin.Android позволяет напрямую использовать Android SDK: Camera2 API, Jetpack, MediaStore и т.д.

Производительность

Xamarin.Forms:

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

  • Сложные UI-элементы и высокочастотное взаимодействие с экраном (например, игры, анимации, кастомные переходы) реализовать сложнее.

Xamarin.Native:

  • Приложения работают максимально близко к нативным, так как UI создаётся вручную с помощью оригинальных компонентов платформы.

  • Более высокая производительность в ресурсоёмких приложениях, требующих точной настройки интерфейса.

Подход к архитектуре

Xamarin.Forms:

  • Стандартный подход — MVVM (Model-View-ViewModel), активно поддерживаемый через встроенный data binding и команды.

  • Упрощает написание тестируемого кода и бизнес-логики, разделённой от интерфейса.

Xamarin.Native:

  • Можно применять различные архитектурные подходы: MVC (как в iOS), MVP, MVVM — по желанию разработчика.

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

Кодовая база и повторное использование

Xamarin.Forms:

  • Максимальное повторное использование кода — часто до 95–100% общего кода при грамотной архитектуре.

  • Только небольшие части (например, кастомные элементы или зависимости от аппаратного обеспечения) реализуются индивидуально для платформ.

Xamarin.Native:

  • Код разделяется на общий (shared project или .NET Standard library) и два отдельных проекта — Android и iOS, в которых пишется UI и специфическая логика.

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

Время разработки

Xamarin.Forms:

  • Быстрее подходит для прототипирования и разработки приложений, которые не требуют сложного дизайна и глубокой кастомизации UI.

  • Позволяет запускать MVP или внутренние корпоративные приложения с минимальными затратами.

Xamarin.Native:

  • Требует больше времени и ресурсов, так как интерфейс разрабатывается отдельно под каждую платформу.

  • Однако этот подход даёт более гибкий и качественный контроль над пользовательским опытом.

Гибкость в кастомизации

Xamarin.Forms:

  • Ограничена в плане визуальных и анимационных возможностей.

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

Xamarin.Native:

  • Полный контроль над пользовательским интерфейсом, включая анимации, переходы, жесты, плавающие кнопки, Material Design/Apple Human Interface Guidelines и другие нативные принципы UX.

Размер приложения

Xamarin.Forms:

  • В зависимости от количества подключённых библиотек и рендереров размер может быть больше, чем у нативных приложений, особенно на iOS из-за AOT-компиляции.

  • При этом общий размер может быть меньше, чем у Xamarin.Native, если использовать общие компоненты и минимизировать зависимости.

Xamarin.Native:

  • Размер приложения может быть меньше при ручном управлении ресурсами и компонентами, но увеличивается при наличии большого количества специфического функционала в каждом из платформенных проектов.

Сценарии использования

Xamarin.Forms:

  • Приложения с простым или стандартным пользовательским интерфейсом.

  • Внутренние корпоративные решения.

  • MVP, быстрые прототипы.

  • Приложения с минимальными различиями между платформами.

Xamarin.Native:

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

  • Продукты, где UX — критически важная часть, особенно под iOS.

  • Игры, приложения для мультимедиа, дополненной реальности, высоконагруженные клиенты.

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

Примеры кода

Xamarin.Forms (XAML):

<StackLayout>
<Label Text="Привет, мир!" FontSize="Large" />
<Button Text="Нажми меня" Clicked="OnButtonClicked" />
</StackLayout>

Xamarin.Native (Android):

protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
var button = FindViewById<Button>(Resource.Id.myButton);
button.Click += (sender, e) =>
{
button.Text = "Нажато!";
};
}

Xamarin.Native (iOS):

public override void ViewDidLoad()
{
base.ViewDidLoad();
var button = new UIButton(UIButtonType.System);
button.Frame = new CGRect(100, 100, 200, 40);
button.SetTitle("Нажми", UIControlState.Normal);
button.TouchUpInside += (sender, e) =>
{
button.SetTitle("Нажато!", UIControlState.Normal);
};
View.AddSubview(button);
}

Оба подхода — Xamarin.Forms и Xamarin.Native — являются частью одной экосистемы, но выбор между ними зависит от конкретных задач, требований к дизайну, бюджета, команды и целей проекта.