Что станет следующим важным моментом для разработки мультиплатформенных приложений?

Хочу рассказать вам об удивительном предложении. Представьте на мгновение, что вы знаете два языка. Один из них - это основанный на стандартах язык разметки, такой как HTML, который позволяет описывать, как должны выглядеть ваши приложения. Второй - это многофункциональный язык программирования, которым пользуются и любят, вероятно, миллионы разработчиков по всему миру. Если вы объедините эти две вещи, как вы могли ошибиться? К сожалению, именно это удалось сделать Xamarin Forms.

И, как и большинство вещей, усваиваемых в среднем, он уходит. Я имею в виду, что даже не Microsoft, буквально люди, владеющие Xamarin, используют его в любых своих больших продуктах, таких как Teams, Outlook и этот список можно продолжить. Вместо этого они обращаются к собственной разработке или к Electron. Так что мы можем просто связать ей лук и минутой молчания рассказать о еще одной отслужившей свой срок кроссплатформенной среде разработки программного обеспечения.

К сожалению, это молчание было бы прервано тем фактом, что Xamarin Forms не выводится полностью на пастбище, а вместо этого формирует основу так называемого пользовательского интерфейса многоплатформенных приложений (MAUI). И он должен приземлиться одновременно с .NET 6.0, но с тех пор перенесен на второй квартал 2022 года. Когда это произойдет, MAUI заменит Xamarin Forms в качестве предложения Microsoft в мобильном пространстве. Естественно, вы могли бы подумать, что большее количество мобильных фреймворков делает разработку более доступной и может быть только хорошей вещью, не так ли?

Я не совсем уверен. Понимаете, около двух лет назад я перешел от Xamarin Forms и могу с уверенностью сказать, что это было лучшее решение, которое я принял в своей карьере программиста. Использование Xamarin Forms было очень неприятным фреймворком, и теперь на его основе создается MAUI. Это немного похоже на привинчивание вращающегося ресторана к Пизанской башне. Аналогия очевидна, но ресторан обречен, если фундамент с самого начала будет тусклым.

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

Поскольку MAUI развивается на основе Xamarin Forms, сейчас самое время рассмотреть, с какими болевыми точками я столкнулся за эти годы с этой структурой.

Опыт разработчика был болезненным

То, на что большинство из нас, разработчиков, чаще всего обращает внимание при создании приложений, это не само приложение, а скорее IDE, в которой мы пишем приложение. В моем случае это Visual Studio 2019. И всякий раз, когда я пытался работать над приложением Xamarin Forms в Visual Studio 2019, это был плохой опыт.

Это странно, потому что Visual Studio сама по себе является прекрасной IDE. Когда я использую его для других своих приложений, он работает довольно хорошо. И все же по какой-то причине Visual Studio замедляла сканирование, когда я работал со своими приложениями Xamarin Forms. Нередки были сбои, странные окна предупреждений, в которых только что было HRESULT, или фраза «Катастрофический сбой». Это не внушало доверия.

Другие области, связанные с разработкой Android, страдали от недостатка доработки и зачастую просто не работали. Например, в эмуляторе Android, который предлагала Visual Studio, все время, пока я его использовал, были проблемы. Вот как выглядит мой сейчас:

Все эмуляторы, которые существуют из-за Android Studio, находятся в состоянии «ошибки», что неверно, потому что они отлично работают в Android Studio. Единственный запущенный эмулятор (выделенный Pixel 2) не уважает, что я нажимаю кнопку «Стоп». Когда я пытаюсь остановить его, выдает эту ошибку.

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

Это просто недостаток доработки - диспетчер эмуляторов Visual Studio должен иметь возможность запускать и управлять эмуляторами, созданными с помощью Android Studio. В конце концов, у них обоих закончился QEMU, и они используют один и тот же эмулятор под капотом. Еще одна доработка: эмуляторы в состоянии «ошибки» не сообщают вам, почему они такие, или что вы можете сделать, чтобы «исправить» их. Подобные проблемы распространены при интеграции Xamarin в Visual Studio в целом.

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

У вас есть Mac и ПК? Если да, то вас ждет особый тип боли. В Windows вы будете использовать Visual Studio 2019, которая в основном функциональна, а когда вы переключитесь на свой Mac, вы будете бесконтрольно плакать при использовании Visual Studio для Mac, где ничего не имеет смысла, а пол - это потолок.

Да, Visual Studio для Mac не подходит. Так было всегда, и, к сожалению, неважно, сколько времени Microsoft уделяет этому процессу, так было всегда. Я уверен, что многие разработчики вложили много времени в среду IDE на протяжении многих лет, и мне неприятно отказываться от нее, но каждый раз, когда я ее использовал, это всегда было плохим опытом. Я могу описать опыт VS для Mac только как «неточный» - все работает не так, как вы ожидаете, и это полностью отличается от Visual Studio для Windows.

Конечно, Microsoft не обязана создавать версию Visual Studio, которая будет выглядеть одинаково на разных платформах. Код Visual Studio сильно отличается от Visual Studio 2019, и это нормально. Один - это текстовый редактор, а другой - надежный инструмент разработки для тонны рабочих нагрузок. И в этом есть смысл - сложная IDE для разработчиков Windows и упрощенный текстовый редактор для всех остальных на разных платформах.

Что не имеет смысла, так это то, где Visual Studio для Mac имеет то же имя и его аналог для Windows, но он не может делать половину того, что может сделать Visual Studio 2019. Поскольку он имеет то же имя, что и Visual Studio 2019 для Windows, он бессмысленно и запутанно фрагментирует опыт разработчика в этой области. Все выглядит и ощущается по-другому, горячие клавиши другие, окно вывода программы где-то совсем другое, и пользоваться им просто неудобно. Это не просто текстовый редактор, потому что у VS Code есть этот уголок рынка. Нет, это IDE, которую вы должны использовать, если у вас есть Mac.

Чтобы продемонстрировать, что я имею в виду, вот как выглядит Visual Studio 2019 в Windows с новым консольным приложением:

А вот как это выглядит в macOS:

Опять же, оба этих продукта имеют одинаковое название «Visual Studio 2019». И все же в Windows и Mac они выглядят совершенно по-разному. Очень утомительно переключаться между разработкой на ПК и Mac, так как вы должны помнить два набора горячих клавиш, два набора того, где все находится, и два способа фактического использования IDE. Я знаю, что Visual Studio 2019 для Windows была разработана с нуля для Windows, а VS для Mac был основан на MonoDevelop, поэтому они начали совсем по-другому. Но это было много лет назад, а версия для Mac по-прежнему не дает надежды на достижение паритета функций.

Какое это имеет отношение к Xamarin Forms или MAUI? Что ж, когда появится MAUI, если вы разрабатываете для ПК и Mac, вам все равно придется выбирать между этими двумя отдельными продуктами, и, поскольку это расстраивает сегодня, это означает, что это будет разочаровывать в будущем.

Вы можете подумать, что «сравнивать на основании этой предпосылки несправедливо - продукты на разных платформах будут выглядеть по-разному». Это понятно, но если вы когда-либо использовали Android Studio, вы бы заметили, что у нее вообще нет этой проблемы. Это выглядит одинаково для Windows, Mac, и Linux. Вместо того, чтобы выделять отдельную IDE для каждой платформы, Google просто основал свою IDE на (и лицензированную) IntelliJ IDEA, которая уже была кроссплатформенной IDE, а затем разместил их материал на вершине.

В результате получается IDE, которая работает одинаково на разных платформах, что очень радует многих разработчиков. Именно так и должна быть кроссплатформенная разработка - все должно выглядеть и ощущаться одинаково на разных платформах.

Вы можете спросить, доступна ли кроссплатформенная .NET IDE для Windows, Mac и Linux? "Там есть." И это здорово. И это выглядит одинаково на всех платформах. Я понятия не имею, как это работает, но, конечно, если бы Google могла лицензировать Android Studio для своих решений кросс-платформенной разработки, они могли бы предоставить лицензию Microsoft Rider для ее кроссплатформенной разработки .NET? Конечно, это должно стоить меньше, чем наем целой команды разработчиков для поддержки Visual Studio для Mac.

Когда все, что ты делаешь, выглядит скучным

Xamarin Forms сосредотачивает свой визуальный слой вокруг концепции, известной как XAML, поэтому для создания любых приложений в Xamarin Forms вам необходимо изучить XAML. Это достаточно справедливо - вам нужно изучить HTML, чтобы создавать веб-сайты, и вы должны научиться использовать Dart, например, для создания приложений Flutter.

Но, как разработчики, мы хотели бы, чтобы те вещи, которые мы изучали, использовались по-разному. И единственные вещи, которые используют XAML, - это Xamarin Forms, Windows Presentation Framework (WPF) и собственные приложения Windows 10, такие как те, что есть в Магазине Windows.

Для создания приложения WPF, вероятно, потребуется довольно конкретный вариант использования. Я не говорю, что вам это не понадобится. Возможно, вы захотите создать высокопроизводительное приложение, которое также будет работать в более старых ОС Windows. И опять же, вы, вероятно, стали бы писать собственные приложения для Windows 10 только в том случае, если бы у вас был очень конкретный вариант использования, или, возможно, вы создавали приложение для XBOX или что-то в этом роде? Я чувствую, что это будет редкость.

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

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

Простая причина этого заключается в том, что Xamarin Forms сопоставляет XAML, который вы пишете, реализации, зависящей от платформы, поэтому элемент управления Label в XAML сопоставляется с соответствующим элементом управления для целевой платформы. Для простых вещей, таких как размещение текста в поле, эти элементы управления работают так, как вы ожидаете, но в тот момент, когда вам нужно что-то более продвинутое (например, градиенты, анимация, радиусы границ и т. Д.), Вы играете за пределами того, что Xamarin Формы могут предложить вам "из коробки".

В случае, если вы ищете определенный вид на Xamarin Forms, вам необходимо написать «настраиваемый модуль визуализации» для платформы, на которую вы нацеливаетесь. Игнорируя тот факт, что написание кода для конкретной платформы в кроссплатформенном приложении в первую очередь сводит на нет цель использования кроссплатформенного решения, необходимость писать эти рендереры действительно является проблемой, и это усугубляется тем фактом, что вы можете взаимодействуют только с системными API нижнего уровня через библиотеку привязки в C #.

Это может показаться странным, но позвольте мне объяснить. Допустим, вы хотите настроить внешний вид границы или придать определенный вид части приложения. Теперь вам нужно создать настраиваемое средство визуализации для конкретной платформы, но не на родном языке этой платформы, таком как Swift или Kotlin, а вместо этого - библиотеку привязки C #, которая привязана к этой конкретной поверхности API устройства.

Поскольку вы говорите на C #, когда базовые платформы говорят на Kotlin или Swift, кажется, что все, что вы говорите, проходит через переводчик, и хотя каждый может понять суть того, что вы говорите, более тонкие детали теряются. Иногда единственные примеры, которые вы можете найти в Интернете, которые дадут вам то, что вы хотите, написаны на этих языках, и вам нужно переписать эти реализации с их родного языка на C #, чтобы попытаться получить то, что вы хотите. Это почти всегда заканчивается плохо, поскольку вы пытаетесь понять достаточно Swift или Kotlin, чтобы что-то выглядело определенным образом.

Проблемы с XAML и View Model

Создание ваших приложений в Xamarin Forms означает, что вы определяете, как ваше приложение выглядит в XAML, а затем создаете модель представления, которая содержит бизнес-логику для каждого отдельного представления. Теоретически это звучит нормально, но на самом деле XAML настолько громоздок и многословен, что попытки использовать его для реализации простых вещей очень быстро становятся очень трудными.

Например, в примере приложения Xamarin Forms у нас есть этот код в нашем AppShell.xaml:

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

Мы также видим ссылки на StaticResource, который находится в нашем app.xaml и выглядит так:

Этот бит XAML каким-то образом занимает около 25 строк для определения основного цвета и того, какого цвета должна быть кнопка, если она включена или отключена. Нетрудно понять, как долго это может длиться, если, например, вы пытаетесь определить какой-нибудь продвинутый стиль.

Еще одна проблема, в которой эта многословность становится проблемой, - это то, где вы определяете, что должно происходить, когда пользователь нажимает кнопку или каким-либо образом взаимодействует с вашим приложением. Я привык к этому, определяя, что должно происходить, например, когда пользователь нажимает кнопку. Но в XAML это слишком сложно и требует от вас определения «командного» поведения. Возьмем, к примеру, эту кнопку:

Здесь нас интересует «привязка» к «OpenWebCommand». Как это работает? Нравится:

Мы определяем ICommand для нашей OpenWebCommand, а затем в нашем конструкторе для ViewModel мы настраиваем, что должно происходить при нажатии на нашу кнопку. В файлах такого размера это не проблема, но в файлах большего размера попытка выяснить, какой код на самом деле запускается, когда пользователь нажимает кнопку, превращается в долгий путь, когда вы пытаетесь ориентироваться в этих моделях представления и заблудитесь. Для меня взаимосвязь между функциональностью кнопки и логикой, которая запускается при нажатии кнопки, не так ясна, как должна быть.

Этот выбор дизайна также делает невероятно трудным выполнение простых вещей, таких как передача параметров в эти команды. XAML позволяет вам указать CommandParameter, который вы должны иметь возможность использовать для передачи данных в ваш ICommand, но поскольку вы не напрямую вызываете функцию из своей модели представления (а вместо этого абстрагируя это через ICommand) вы теряете безопасность типов.

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

Ни одна из этих проблем не решается с помощью MAUI

Плохой опыт разработчика, внешний вид приложений, проблема с XAML и другие основные проблемы не будут решены MAUI. Итак, если вы уже знакомы с Xamarin Forms и ждете, пока появится MAUI, но пока не на 100% в восторге от этого опыта, то это отличная возможность подумать о том, чтобы изучить что-то еще.

Вы всегда можете создавать свои приложения изначально, или, если у вас все еще есть кроссплатформенные требования, вы можете посмотреть что-то вроде Flutter или React Native. В моем случае я перешел на Flutter, и с тех пор я получаю от него огромное удовольствие. У него есть свои проблемы, но, по моему опыту, пользоваться им гораздо приятнее.

Возможно, самый большой позор состоит в том, что Xamarin Forms всегда задатками отличной идеи. Возможно, если бы Microsoft использовала его для внутренних целей в широко используемых приложениях, таких как Teams или Outlook, и испытала бы все проблемы и невзгоды, связанные с этим, то это привело бы к правильному курсу гораздо раньше.

Нет причин, по которым этого не могло бы произойти - приложения Xamarin Forms на самом деле были бы более производительными, чем их аналоги в Electron, поскольку C # - это компилируемый язык, а Javascript - интерпретируемый язык. С помощью специфичных для платформы битов, реализованных для средств визуализации, или определенной бизнес-логики, использующей собственный код для оптимизации, это могло бы проложить путь к действительно отличному приложению.

Вместо этого Xamarin Forms был исключен из собственных приложений Microsoft, а такие приложения, как Teams, написаны на Electron. Если Microsoft не будет использовать его в своих больших и важных приложениях, тогда зачем мне?

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

Я действительно надеюсь, что MAUI откроет путь к отличному опыту разработки мультиплатформенных приложений. Но, судя по прошлому Xamarin Forms и сегодняшнему положению дел, просто трудно понять, как это произойдет. Хотя я бы хотел ошибаться.