Декларативный UI в Android и iOS

Разберем, как Google и Apple предлагает разрабатывать интерфейсы в следующие несколько лет.

В мае 2019 года Google представила UI-фреймворк Jetpack Compose. Apple через месяц на WWDC показала SwiftUI. Подходы схожи между собой, которые со временем должны прийти на смену ConstraintLayout и AutoLayout.

В iOS UI-компоненты создаются с помощью Interface Builder, рекомендуется использовать Storyboard — в одном файле можно сделать не только верстку одного экрана, а сразу многих, при это связав их между собой переходами, что очень наглядно.

Напрямую с XML в iOS работать не нужно — все делается через редактор. В Android исторически UI создавался напрямую в XML-формате, есть возможность просмотреть сразу предпросмотр результата. Аналог Storyboard в Android — Navigation Component.

Jetpack Compose

Для того, чтобы воспользоваться новым фреймворком, придется установить Android Studio 4.0 Preview. Пока рано использовать этот подход в реальных проектах — подождать стоит как минимум год. За это время Google соберет все ошибки фреймворка и подготовит его для релиза. На официальном сайте для разработчиков есть tutorial, в котором сейчас 3 урока, и документация. В документации достаточно подробно разъясняются базовые вещи работы с UI с помощью Compose. По окончании уроков получается экран с изображением, стилизованным текстом в стиле Material.

@Composable fun NewsStory() { val image = +imageResource(R.drawable.header) MaterialTheme { Column( modifier = Spacing(16.dp) ) { Container(modifier = Height(180.dp) wraps Expanded) { Clip(shape = RoundedCornerShape(8.dp)) { DrawImage(image) } } HeightSpacer(16.dp) Text("A day in Shark Fin Cove") Text("Davenport, California") Text("December 2018") } } }

Небольшой пример экрана с изображением и тремя строчками текста.

Использование в Activity.

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { NewsStory() } } }

Compose входит в состав Jetpack, что делает возможным использование даже в старых версиях Android. Использование Kotlin позволяет писать UI в декларативном стиле прямо в коде вместо XML. В случае, если мы хотим обновить UI при действиях пользователя, обновлении данных из сети, нам нужно сделать data class с аннотацией @Model, чтобы свойства были наблюдаемыми. Затем при изменении этого класса UI-компонент автоматически обновится актуальными данными. Фреймворк не только задает правила создания экранов, он еще и говорит нам как правильно работать с данными. А работа с ними в Android — большая тема для дискуссий. Так вот Compose говорит нам, что мы должны разрабатывать UI c учетом так называемого “однонаправленного поток данных”. Compose проясняет кто отвечает за состояние и как должны обрабатываться события, подобно тому, как это обрабатывает React. Разработка ведется с тестовыми данными в режиме Preview. Этот код предназначен лишь для разработки и не вызовется при запуске приложения на устройстве или эмуляторе, определить этот код можно по аннотации @Preview.

@Preview @Composable fun DefaultPreview() { NewsStory() }

Для обратной совместимости можно использовать аннотацию @GenerateView и получить view по id.

@Composable @GenerateView fun Greeting(name: String) {/* ... */} <GreetingView android:id="@+id/greeting" app:name="@string/greeting_name" /> val greeting: GreetingView = findViewById(R.id.greeting) greeting.setName("Jim")

SwiftUI

У Apple так же есть набор уроков, я бы даже назвал это курсом — уроков значительно больше, чем в Compose, они подробнее, содержат готовые проекты, у каждого указано ориентировочное время выполнения. В конце урока можно ответить на проверочные вопросы. Примеры хоть и тестовые, но они далеко ушли от “Hello, world”. Сайт оформлен очень удобно и красиво — анимации переходов, все на высоте. Рекомендую хотя бы взглянуть.

Простой пример уже в SwiftUI.

struct ContentView: View { var body: some View { VStack(alignment: .leading, spacing: 8) { Image("image") .cornerRadius(8) VStack(alignment: .leading, spacing: 2) { Text("A day in Shark Fin Cove") .font(.title) Text("Davenport, California") Text("December 2018") Spacer() } } .padding() } }

Предпросмотр можно включить, написав так

struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }

Релиз SwiftUI получился более масштабным среди разработчиков своей платформы и далее я поясню почему.

Во-первых, решение уже можно использовать в production. Да, нет обратной совместимости с версиями меньше iOS 13, но Apple редко показывает что-то с претензией на далекое будущее. Раз показали, значит, уверены, что это будет работать, пусть и не на все 100%. Здесь могу заметить, что SwiftUI хоть и полноценно доступен в текущих версиях Xcode, тем не менее, еще есть компоненты, которых не хватает для полноценной разработки, документация не идеальная, да и мало кто готов отбросить порядка 10-15% пользователей старых операционных систем.

Во-вторых, вместе со SwiftUI Apple представила фреймворк для реактивного программирования Combine (да, в Swift достаточно популярен RxSwift, как и RxKotlin в Android) и другие интересные фичи Swift (например, property wrapper), которые стоит использовать совместно со SwiftUI.

В-третьих, реализация UI с помощью SwiftUI достаточно сильно меняет архитектуру приложения — надобность контроллера в MVC отпадает. Навигация происходит сразу во view. Действия на UI обрабатываются на View, изменяя данные.

В-четвертых, создавать UI можно как и написанием кода, так и набрасыванием элементов в редакторе — код подставится автоматически. Это помогает в процессе обучения, когда еще плохо помнишь наизусть разные UI-компоненты. В Jetpack Compose создание только через код.

Доступные компоненты в SwiftUI

Так же немаловажный фактор — SwiftUI доступен не только на iOS, но и на watchOS, macOS, tvOS.

Выводы

Google традиционно показывает новинки в альфа-версиях, Apple же наоборот — инструменты, которые можно использовать здесь и сейчас. У обоих подходов есть свои плюсы и минусы. Но уже понятно, что постепенно в ближайшие несколько лет разработка UI новых проектов будет только на Compose и SwiftUI. Фреймворки декларативного UI уменьшают порог входа для новичков, ускоряют процесс создания приложений. Подход не является чем-то новым в разработке — React, Flutter, так и другие open source-решения предлагали похожие решения и ранее, но Google и Apple постарались сделать все проще и лучше.

На текущий момент я бы не советовал использовать даже доступный SwiftUI в production, но с выходом новой версии iOS летом, фреймворк наверняка станет стабильнее.

Compose же пока в альфа-версии, для Android-разработчиков это действительно хорошая возможность поучаствовать в тестировании и улучшении перед финальным релизом.

0
9 комментариев
Написать комментарий...
Denis Kiselev

Судя по интернетам - swiftUI сам по себе - довольно стабилен. Другой вопрос, что сама iOS 13 получилась с кучей мелких багов - причём настолько, что Эппл декларировал смену процесса разработки для предотвращения нынешней ситуации

Ответить
Развернуть ветку
Ilya Che

А можно несколько аргументов в сторону этого заявления “На текущий момент я бы не советовал использовать даже доступный SwiftUI в production”? (если речь идет о новых разработках).
SwiftUI ведь совместим с UIkit. 

Ответить
Развернуть ветку
Denis Bystruev

Скорее всего, имеется в виду, что со SwiftUI сейчас вы потеряете половину пользователей, так как для неё требуется iOS 13, а до 95% проникновения она дойдёт только через год — к моменту выпуска iOS 14.

Обычно сам Apple рекомендует поддерживать две последние версии — в данный момент это iOS 12 и iOS 13.  Но большинство заказчиков и на это не готовы, в требованиях до сих пор ставят «включая поддержку iOS 10».

Ответить
Развернуть ветку
Ilya Che

На декабрь 2019 доля iOS13 в Северной Америке более 70%, в мире – более 65%.
К лету эта цифра может значительно вырасти (как раз время на разработку и тесты)
Плюс стоит учитывать особенности по ЦА, региону, продукту и тд.

 
 Насчет поддержки согласен, если есть что и кого поддерживать. 

Ответить
Развернуть ветку
Denis Bystruev

Я сам заказчиков агитирую оставить только iOS 13 и отсечь всех, кто ниже (из-за RealityKit, в котором удобнее организовывать совместную работу в AR — то, что сейчас все хотят), но никто не соглашается.  Все хотят минимум iOS 10, в крайнем случае 11.

Ответить
Развернуть ветку
Ilya Che

Забавные заказчики. Весь мир имеет на девайсах iOS 12 + 13. Что ж это за проекты они такие хотят. Может они и скевоморфизм просят? )

Надо давить на SwiftUI. Причем не только даже на клиентов сколько и на девов. А то ходили тут истории про девов, которые хейтили SwiftUI за кривость, а на вопрос пробовали ли что-то покодить отвечали "нет".

Ответить
Развернуть ветку
Denis Bystruev

Обычные заказчики с Upwork и FL.ru.

Нет, все хотят чтобы на iOS 13 было красиво, но чтобы iOS 10 тоже поддерживалось.  И желательно, чтобы ещё и Android за ту же цену.

Сейчас вот на Flutter смотрю для таких

Ответить
Развернуть ветку
Denis Bystruev

У Google есть же ещё Flutter https://flutter.dev — полностью декларативный UI для всех платформ.

Работает уже сейчас практически на всех Android и iOS-устройствах, до которых можно дотянуться. Компилирует из Dart нативный Objective C/Swift код для Xcode и Java/Kotlin для Android Studio.
 
 На конференции Flutter Interact https://developers.google.com/events/flutter-interact Google рассказывал, что на проект перебрасываются лучшие программисты, персонал вырос вдвое и что это стратегическое будущее — работа приложений на любых устройствах от телефонов до Smart Display. 

 Не совсем понятно, как они будут сосуществовать с Jetpack Compose.

Ответить
Развернуть ветку
George Khromchenko

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

Ответить
Развернуть ветку
6 комментариев
Раскрывать всегда