Хабрахабр

[Перевод] Реализуем UI в iOS: улучшаем, ускоряем, масштабируем

Меня зовут Азат Зулькарняев, я занимаюсь разработкой iOS-приложений в компании Badoo. Привет! Мой коллега Алексис Сантос написал статью о том, с какими проблемами мы столкнулись и как двигались в сторону их разрешения при работе над этой задачей. При создании мобильных приложений большая часть времени уходит на разработку UI, и оптимизация этого процесса всегда является актуальной темой в среде разработчиков. Также рекомендую посмотреть запись недавнего доклада Игоря Савельева на Mobius 2018. Я решил поделиться с вами переводом.

В нём подробно рассматривается работа дизайнеров из разных сфер: архитектура, графический дизайн, мода и т. Несколько месяцев назад я наткнулся на очень интересный документальный сериал от Netflix — «Абстракция: Искусство дизайна». Нетрудно заметить определённое сходство их работы с деятельностью iOS-разработчиков, занимающихся реализацией пользовательских интерфейсов. д. Тем не менее совсем забывать об общей картине нельзя — иначе, когда придёт время сборки, могут возникнуть трудности. В частности, ведя работу над крупным проектом, дизайнеры стараются разбить её на множество мелких задач по принципу «разделяй и властвуй» и получают возможность собрать все элементы воедино на более позднем этапе.
Такое разделение даёт возможность сконцентрироваться на отдельной проблеме, не беря во внимание взаимосвязь компонентов.

Nike, отправив новые кроссовки на полки магазинов, больше не будет обновлять их внешний вид. С другой стороны, в процессе просмотра я заметил, что окончательный дизайн многих продуктов — обуви, постеров или зданий — не претерпевает со временем никаких изменений. К сожалению или к счастью, к дизайну мобильных приложений этот принцип неприменим — разработчики должны быть готовы к частым изменениям внешнего вида своих продуктов. В некоторых случаях продукт выглядит всё так же здорово и через 20 лет.


Nike Air Max 97,  Empire State Building (Нью Йорк)

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

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

Если вкратце, то процесс нашей UI-разработки не был чётко структурирован.

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

  • не было чётких правил взаимодействия с дизайнерами: коллеги не всегда были в курсе нашей работы, и это приводило к тому, что они создавали новые компоненты, по сути, аналогичные уже существующим, но выглядящие по-другому;
  • у нас не было универсальной модели реализации новых UI-компонентов: каждый разработчик реализовывал компоненты по-своему, что усложняло поддержку проекта;
  • дублирование кода тоже не делало кодовую базу лучше.

Как следствие:

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

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

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

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

По нашей задумке, они должны содержать все необходимые UI-компоненты (наподобие UIKit от Apple). Мы решили создать пару фреймворков, которые назвали BadooUIKit. Каждый из классов фреймворка соответствует UI-элементу какого-либо приложения (наша компания разрабатывает и другие приложения, но в данный UIKit мы добавили только компоненты, использующиеся в Badoo).

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

Но как быть, если тот или иной UI-компонент можно использовать в разных приложениях?

В нём содержатся все компоненты, подходящие для других приложений. На этот случай мы создали ещё один фреймворк — Platform_UIKit.

Вы просто разом перенесли все UI в новый фреймворк?

Вместо этого мы создавали каждый новый UI-элемент внутри фреймворка, а уже существовавшие компоненты переносили, только если затрагивали их в рамках работы над своими задачами. Нет, это весьма проблематично. Прежде всего мы переносили базовые элементы вроде шрифтов, цветов и кнопок. Иногда компонент было трудно перенести из-за слишком большого количества зависимостей — тогда мы занимались им отдельно. Чтобы было легче, мы сделали это уже после создания инфраструктуры. Затем, возведя фундамент, мы перенесли во фреймворк весь интерфейс нашего чата.

Офтоп: если вас интересует процесс создания компонентов, ловите классную статью моего коллеги Валерия Чевтаева myltik.

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

Мы можем импортировать данные из Platform_UIKit в BadooUIKit, но не наоборот: Platform_UIKit должен сохранять независимость.

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

Плюсы использования UIKit:

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

BadooUIKit помог нам решить значительную часть проблем, но мы понимали, что нет предела совершенству.

Можно ли настроить поиск компонентов и увидеть каждый из них в различных цветовых гаммах? Как увидеть все UI-компоненты по отдельности? Можно ли создать для дизайнеров каталог всех существующих и реализованных UI-компонентов? Можно ли облегчить их тестирование?

Так появился Badoo Gallery. Запустив BadooUIKit, мы решили создать простенькое отдельное приложение-каталог для использования внутри компании.

При его создании мы пользовались самыми разными средствами, которые облегчают взаимодействие с компонентами. Badoo Gallery — инструмент, помогающий разработчикам, дизайнерам и даже членам продуктовой команды увидеть все UI-компоненты в наглядной, доступной форме.

В качестве ключевых мы выделили следующие функции: Поскольку наше приложение не было предназначено для публикации в App Store, мы могли добавить любой инструмент, какой считали нужным.

  • поиск компонентов;
  • сортировка компонентов по названию;
  • добавление элементов в избранное;
  • переключение между стилями — чтобы можно было посмотреть, как компонент будет выглядеть в том или ином оформлении;
  • FLEX;
  • счётчик FPS.


Каждый компонент может находиться в разных состояниях в зависимости от действий пользователя и внутренней логики приложения. Например, UIButton имеет пять состояний: 1) по умолчанию, 2) выделенное, 3) при наведении, 4) при нажатии и 5) заблокированное.

Подробнее читайте здесь. Интересно?

Конечно, состояния наших кнопок могут отличаться от состояний кнопок UIKit Apple. Кроме того, нам хотелось иметь возможность представить все возможные комбинации в одном месте — мы поступаем так с каждым экраном каждого компонента.

Основные преимущества Badoo Gallery:

  • возможность создания перечня реализованных UI-компонентов;
  • лёгкий поиск UI-компонентов: каждый из нас может увидеть все возможные варианты внешнего вида UI-компонента и найти им применение;
  • облегчённый поиск уже существующих компонентов помогает убеждать дизайнеров использовать их повторно;
  • время компиляции такого маленького приложения очень мало, это помогает значительно сократить период разработки;
  • функция избранного помогает найти компоненты, реализованные в данный момент;
  • добавление внешних инструментов вроде FPS, FLEX и MultiBrand позволяет измерять качество UI-компонентов и совершенствовать их;
  • все компоненты помещены в отдельный фреймворк и представлены в изолированной среде — тестирование стало гораздо проще.

Новые инструменты помогли решить большинство проблем, описанных в начале статьи, но некоторые вопросы остались без ответа.

Как защитить компоненты и другие части приложения от неблагоприятного воздействия новых параметров подкомпонентов? Можем ли мы быть уверены в том, что после внесения изменений UI будет выглядеть так, как мы задумали?

В Сети немало статей об организации UI-тестирования на iOS. Найти ответы на эти вопросы помогут тесты UI-компонентов. Кроме того, существует множество различных инструментов, предназначенных для тестирования тех или иных сторон интерфейса.

Мы решили проводить snapshot-тестирование, внедрив одну из самых популярных в то время open-source-утилит iOSSnapshotTestCase (ранее известную как FBSnapshotTestCase, поскольку создана она была компанией Facebook).

Узнать больше о тестировании с использованием скриншотов и об этом фреймворке вы можете по одной из этих ссылок:

Нам нужен был способ тестирования уже имевшихся в BadooUIKit компонентов, чтобы избежать регрессии при обновлении компонентов приложения. Мы также хотели по максимуму автоматизировать процесс внедрения новых snapshot-тестов.

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

Этот репозиторий способен как демонстрировать список компонентов в галерее, так и открывать доступ к ним при помощи классов snapshot-тестов. Все находящиеся в BadooUIKit компоненты содержатся в классе-репозитории, предоставляющем доступ ко всем компонентам. Это освобождает нас от двойной работы — создания объектов и подготовки различных состояний для каждого из компонентов — поскольку всё это уже было сделано, когда мы вводили компонент в галерею.

Вот ответы на самые распространённые вопросы о тестировании со снимками.

Где хранятся снепшоты?

Мы опасались, что это может привести к его раздуванию, но на деле всё оказалось не так плохо. Мы храним их прямо в Git-репозитории. На данный момент папка со скриншотами занимает около 11 Мб, что, как нам кажется, терпимо. Как правило, мы тестируем небольшие компоненты, а потому скриншоты весят очень мало.

Вы тестируете все возможные разрешения во всех возможных окружениях?

А вот проблем может быть достаточно: тесты станут ненадёжными, папка со снимками — более объёмной, а тестовый набор будет сложнее поддерживать. Нет, пользы от такого подхода мало. Кроме того, наша система CI настроена на использование того же симулятора, который использовался для создания снепшота. Мы прагматично проводим тесты только для самых популярных устройств.

Способны ли snapshot-тесты охватить весь интерфейс?

Мы в Badoo проводим различные тесты для различных уровней приложения. Думаю, что нет. Например, функциональные (при помощи фреймворков Calabash и KIF) и интеграционные.

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

Вот некоторые из уроков, которые мы усвоили в ходе работы:

  • перенос всех действующих компонентов — нелёгкая задача, но, реализовав систему проектирования и предложив команде её использовать, вы увидите, как быстро вырастет число компонентов: перенос используемых разработчиками компонентов не только автоматически увеличивает количество переиспользуемых UI-элементов вашей системы, но и помогает существующим элементам освободиться от зависимостей; в будущем это позволит переносить больше компонентов;
  • дизайнерам нравится повторно использовать компоненты (убедить их делать это становится проще, когда есть возможность показать полностью рабочий компонент, отвечающий их требованиям);
  • экономить время необходимо; все мы знаем, что длительность компиляции проектов на Swift и Objective-C оставляет желать лучшего, при этом приложение Badoo Gallery легковесно и очень быстро компилируется; мы поняли, что гораздо удобнее реализовывать UI-компоненты непосредственно с помощью галереи, а затем пользоваться ими через основное приложение, где компиляция идёт не так быстро;
  • объединив все компоненты в UIKit и запустив приложение-галерею, в котором их можно тестировать, мы сделали весь процесс тестирования гораздо эффективнее и проще.

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

Не пропустите! Кристиано Растелли написал несколько увлекательных статей о том, как появилась система Cosmos.

Работу над проектом вёл не один человек — в той или иной степени в ней участвовала вся iOS-команда Badoo, включая менеджеров, разработчиков и тестировщиков. Я благодарю их всех, ведь каждый из них был на борту с самого начала пути.

Спасибо нашим потрясающим дизайнерам, которые всегда готовы приложить максимум усилий для усовершенствования процесса проектирования.

Особая благодарность Александру Зимину: за множество предложенных улучшений, посещение бесчисленных планёрок, а также за поддержку, оказанную мне в этом приключении.

Также благодарю Алиссу Ордильяно за прекрасные иллюстрации, сделавшие эту статью доступнее.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть