- PVSM.RU - https://www.pvsm.ru -
Привет! Меня зовут Азат Зулькарняев, я занимаюсь разработкой iOS-приложений в компании Badoo. При создании мобильных приложений большая часть времени уходит на разработку UI, и оптимизация этого процесса всегда является актуальной темой в среде разработчиков. Мой коллега Алексис Сантос написал статью [1] о том, с какими проблемами мы столкнулись и как двигались в сторону их разрешения при работе над этой задачей. Я решил поделиться с вами переводом. Также рекомендую посмотреть запись недавнего доклада [2] Игоря Савельева на Mobius 2018.
Несколько месяцев назад я наткнулся на очень интересный документальный сериал от Netflix — «Абстракция: Искусство дизайна». В нём подробно рассматривается работа дизайнеров из разных сфер: архитектура, графический дизайн, мода и т. д. Нетрудно заметить определённое сходство их работы с деятельностью iOS-разработчиков, занимающихся реализацией пользовательских интерфейсов. В частности, ведя работу над крупным проектом, дизайнеры стараются разбить её на множество мелких задач по принципу «разделяй и властвуй» и получают возможность собрать все элементы воедино на более позднем этапе.
Такое разделение даёт возможность сконцентрироваться на отдельной проблеме, не беря во внимание взаимосвязь компонентов. Тем не менее совсем забывать об общей картине нельзя — иначе, когда придёт время сборки, могут возникнуть трудности.
С другой стороны, в процессе просмотра я заметил, что окончательный дизайн многих продуктов — обуви, постеров или зданий — не претерпевает со временем никаких изменений. Nike, отправив новые кроссовки на полки магазинов, больше не будет обновлять их внешний вид. В некоторых случаях продукт выглядит всё так же здорово и через 20 лет. К сожалению или к счастью, к дизайну мобильных приложений этот принцип неприменим — разработчики должны быть готовы к частым изменениям внешнего вида своих продуктов.
Nike Air Max 97, Empire State Building (Нью Йорк)
Многие iOS-разработчики, работая над крупными и сложными приложениями, тратят много времени на создание интерфейсов, определение взаимосвязей объектов и оттачивание мелких деталей. Для эффективной работы необходимо держать в уме то, как должно выглядеть приложение в целом, и столь же важно думать о его разделении на отдельные компоненты, которые впоследствии переиспользуются при разработке элементов приложения.
Наша команда выпускает новые релизы еженедельно, и каждый из них содержит новые функции, улучшения и другие изменения, влияющие на пользовательский интерфейс. Мы всегда стремимся работать максимально быстро и качественно, однако год назад в процессе разработки UI обнаружили несколько проблем.
Если вкратце, то процесс нашей UI-разработки не был чётко структурирован.
На практике это означало, что запуск любой новой функции мог привести к самым непредсказуемым последствиям. Например:
Как следствие:
Конечно, все эти проблемы не могли исчезнуть по мановению волшебной палочки. Чтобы изменить порядок вещей, нужно было прийти к согласию между различными командами и убедить всех участников процесса, что перемены необходимы.
Как нельзя кстати пришёлся принцип «разделяй и властвуй». Мы начали с малого, поочередно выделили проблемы, после чего шаг за шагом пришли к глобальному решению. Ниже я расскажу, как нам это удалось.
Мы подошли к решению проблемы со всей серьёзностью и начали с основ. Прежде всего нужно было избавиться от дублирования кода. Для этого мы унифицировали используемые компоненты, собрав их воедино.
Мы решили создать пару фреймворков, которые назвали BadooUIKit. По нашей задумке, они должны содержать все необходимые UI-компоненты (наподобие UIKit от Apple). Каждый из классов фреймворка соответствует UI-элементу какого-либо приложения (наша компания разрабатывает и другие приложения, но в данный UIKit мы добавили только компоненты, использующиеся в Badoo).
Каждое приложение обладает собственными шрифтами, расцветкой, оформлением полей и другими атрибутами, а потому очень полезно иметь таблицу стилей, относящуюся к конкретному приложению.
Но как быть, если тот или иной UI-компонент можно использовать в разных приложениях?
На этот случай мы создали ещё один фреймворк — Platform_UIKit. В нём содержатся все компоненты, подходящие для других приложений.
Вы просто разом перенесли все UI в новый фреймворк?
Нет, это весьма проблематично. Вместо этого мы создавали каждый новый UI-элемент внутри фреймворка, а уже существовавшие компоненты переносили, только если затрагивали их в рамках работы над своими задачами. Иногда компонент было трудно перенести из-за слишком большого количества зависимостей — тогда мы занимались им отдельно. Прежде всего мы переносили базовые элементы вроде шрифтов, цветов и кнопок. Затем, возведя фундамент, мы перенесли во фреймворк весь интерфейс нашего чата. Чтобы было легче, мы сделали это уже после создания инфраструктуры.
Офтоп: если вас интересует процесс создания компонентов, ловите классную статью [3] моего коллеги Валерия Чевтаева myltik [4].
Одно из главных требований к фреймворкам — отсутствие зависимости от других фреймворков и классов, не относящихся к UI. В частности, мы никогда не импортируем модели из основного приложения, относящиеся к сетевому уровню классы, аналитику и т. д. Благодаря этому мы получаем возможность повторного использования компонентов:
Мы можем импортировать данные из Platform_UIKit в BadooUIKit, но не наоборот: Platform_UIKit должен сохранять независимость.
Создание этих фреймворков не потребовало особого труда, равно как и их последующая поддержка. Каждый новый проект Badoo отличается от предыдущего, и нам бывает непросто поддерживать описанную структуру, но наше решение принесло пользу как в ближайшей, так и в отдалённой перспективе.
Плюсы использования UIKit:
BadooUIKit помог нам решить значительную часть проблем, но мы понимали, что нет предела совершенству.
Как увидеть все UI-компоненты по отдельности? Можно ли настроить поиск компонентов и увидеть каждый из них в различных цветовых гаммах? Можно ли облегчить их тестирование? Можно ли создать для дизайнеров каталог всех существующих и реализованных UI-компонентов?
Запустив BadooUIKit, мы решили создать простенькое отдельное приложение-каталог для использования внутри компании. Так появился Badoo Gallery.
Badoo Gallery — инструмент, помогающий разработчикам, дизайнерам и даже членам продуктовой команды увидеть все UI-компоненты в наглядной, доступной форме. При его создании мы пользовались самыми разными средствами, которые облегчают взаимодействие с компонентами.
Поскольку наше приложение не было предназначено для публикации в App Store, мы могли добавить любой инструмент, какой считали нужным. В качестве ключевых мы выделили следующие функции:
Каждый компонент может находиться в разных состояниях в зависимости от действий пользователя и внутренней логики приложения. Например, UIButton имеет пять состояний: 1) по умолчанию, 2) выделенное, 3) при наведении, 4) при нажатии и 5) заблокированное.
Интересно? Подробнее читайте здесь [6].
Кроме того, нам хотелось иметь возможность представить все возможные комбинации в одном месте — мы поступаем так с каждым экраном каждого компонента. Конечно, состояния наших кнопок могут отличаться от состояний кнопок UIKit Apple.
Основные преимущества Badoo Gallery:
Новые инструменты помогли решить большинство проблем, описанных в начале статьи, но некоторые вопросы остались без ответа.
Можем ли мы быть уверены в том, что после внесения изменений UI будет выглядеть так, как мы задумали? Как защитить компоненты и другие части приложения от неблагоприятного воздействия новых параметров подкомпонентов?
Найти ответы на эти вопросы помогут тесты UI-компонентов. В Сети немало статей об организации UI-тестирования на iOS. Кроме того, существует множество различных инструментов, предназначенных для тестирования тех или иных сторон интерфейса.
Мы решили проводить snapshot-тестирование, внедрив одну из самых популярных в то время open-source-утилит iOSSnapshotTestCase (ранее известную как FBSnapshotTestCase, поскольку создана она была компанией Facebook).
Узнать больше о тестировании с использованием скриншотов и об этом фреймворке вы можете по одной из этих ссылок:
Нам нужен был способ тестирования уже имевшихся в BadooUIKit компонентов, чтобы избежать регрессии при обновлении компонентов приложения. Мы также хотели по максимуму автоматизировать процесс внедрения новых snapshot-тестов.
Выше я уже рассказывал о созданной нами галерее, содержащей перечень всех компонентов и состояний, которые может принимать каждый компонент. Это очень удобно, поскольку в этом случае тесты могут запускаться на базе Badoo Gallery как хост-приложения.
Все находящиеся в BadooUIKit компоненты содержатся в классе-репозитории, предоставляющем доступ ко всем компонентам. Этот репозиторий способен как демонстрировать список компонентов в галерее, так и открывать доступ к ним при помощи классов snapshot-тестов. Это освобождает нас от двойной работы — создания объектов и подготовки различных состояний для каждого из компонентов — поскольку всё это уже было сделано, когда мы вводили компонент в галерею.
Вот ответы на самые распространённые вопросы о тестировании со снимками.
Где хранятся снепшоты?
Мы храним их прямо в Git-репозитории. Мы опасались, что это может привести к его раздуванию, но на деле всё оказалось не так плохо. Как правило, мы тестируем небольшие компоненты, а потому скриншоты весят очень мало. На данный момент папка со скриншотами занимает около 11 Мб, что, как нам кажется, терпимо.
Вы тестируете все возможные разрешения во всех возможных окружениях?
Нет, пользы от такого подхода мало. А вот проблем может быть достаточно: тесты станут ненадёжными, папка со снимками — более объёмной, а тестовый набор будет сложнее поддерживать. Мы прагматично проводим тесты только для самых популярных устройств. Кроме того, наша система CI настроена на использование того же симулятора, который использовался для создания снепшота.
Способны ли snapshot-тесты охватить весь интерфейс?
Думаю, что нет. Мы в Badoo проводим различные тесты для различных уровней приложения. Например, функциональные (при помощи фреймворков Calabash и KIF) и интеграционные.
Разумеется, в ходе построения новой платформы мы многому научились — и продолжаем учиться. Описанные выше инструменты и процессы появились около года назад и до сих пор развиваются. На данном этапе можно заключить, что все они приносят пользу разработчикам и компании в целом.
Вот некоторые из уроков, которые мы усвоили в ходе работы:
Мы уделяем много внимания каждому из наших продуктов и хотим, чтобы все они обладали универсальным и привлекательным интерфейсом. Для того чтобы наши пользователи получали максимальное удовольствие от их использования, мы решили произвести глобальные перемены. При содействии дизайнеров и продуктовой команды мы вводим новую единую систему проектирования, получившую название Cosmos.
Кристиано Растелли [10] написал несколько увлекательных статей [11] о том, как появилась система Cosmos. Не пропустите!
Работу над проектом вёл не один человек — в той или иной степени в ней участвовала вся iOS-команда Badoo, включая менеджеров, разработчиков и тестировщиков. Я благодарю их всех, ведь каждый из них был на борту с самого начала пути.
Спасибо нашим потрясающим дизайнерам, которые всегда готовы приложить максимум усилий для усовершенствования процесса проектирования.
Особая благодарность Александру Зимину [12]: за множество предложенных улучшений, посещение бесчисленных планёрок, а также за поддержку, оказанную мне в этом приключении.
Также благодарю Алиссу Ордильяно [13] за прекрасные иллюстрации, сделавшие эту статью доступнее.
Автор: azat_z
Источник [14]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ui/309280
Ссылки в тексте:
[1] статью: https://badootech.badoo.com/implementing-ui-in-ios-better-faster-and-it-scales-9788659e482
[2] недавнего доклада: https://www.youtube.com/watch?v=H0GPHz0FvKk&index=2&list=PL3xVZC4USRNQcy9yfl8ZVGuAM7Pz-1F7Z
[3] классную статью: https://habr.com/ru/company/badoo/blog/421559/
[4] myltik: https://habr.com/ru/users/myltik/
[5] FLEX: https://github.com/Flipboard/FLEX
[6] здесь: https://developer.apple.com/documentation/uikit/uibutton
[7] https://github.com/uber/ios-snapshot-test-case/: https://github.com/uber/ios-snapshot-test-case/
[8] https://www.objc.io/issues/15-testing/snapshot-testing/: https://www.objc.io/issues/15-testing/snapshot-testing/
[9] https://ashfurrow.com/blog/snapshot-testing-on-ios/: https://ashfurrow.com/blog/snapshot-testing-on-ios/
[10] Кристиано Растелли: https://twitter.com/areaweb
[11] статей: https://badootech.badoo.com/from-zero-to-cosmos-part-1-2d080fe35bf2
[12] Александру Зимину: https://twitter.com/ziminalex
[13] Алиссу Ордильяно: http://www.instagram.com/alysienne
[14] Источник: https://habr.com/ru/post/440720/?utm_source=habrahabr&utm_medium=rss&utm_campaign=440720
Нажмите здесь для печати.