Разработка
red_mad_robot

FigmaExport: как автоматизировать экспорт UI-Kit из Figma в Xcode и Android Studio проекты

Даня Субботин, железный iOS-разработчик Redmadrobot, рассказывает, как можно облегчить себе жизнь и начать экспортировать ресурсы из Figma напрямую в Xcode и Android Studio за несколько секунд.

Все больше команд мобильной разработки переходят на Figma. Раньше многие (и мы тоже) использовали связку Sketch и Zeplin или Figma и Zeplin. Это было удобно.

Но когда на одном из проектов мы добавили поддержку темной темы, то ситуация ухудшилась. Zeplin её не поддерживает, поэтому приходится искать пути обхода, которые заставляют задуматься: а нужен ли он нам теперь?

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

Отказавшись от Zeplin и переехав в Figma, мы (разработчики) начали испытывать боль при экспорте UI-Kit из Figma. Figma, в отличие от Zeplin, никак не взаимодействует с Xcode и Android Studio. Плагины не позволяют Figma тесно интегрироваться с ними.

Мы нашли утилиту командной строки, которая экспортировала цвета и текстовые стили, но нам она не подошла — не поддерживала экспорт картинок и тёмную тему. Именно поэтому я написал свою утилиту. Но немного подробнее о проблемах.

Почему мобильным разработчикам неудобно экспортировать ресурсы из Figma

Проблема #1: отсутствие возможности экспортировать цвета

Что мы — разработчики видим, когда открываем UI-Kit в Figma? В самом простом случае — несколько кружочков разных цветов.

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

У Figma нет возможности экспортировать цвета. Максимум, что можно сделать, это выделить цвет и скопировать HEX значение. И если дизайнер что-то поменяет, то в случае большой палитры, разработчику придется потратить много времени, чтобы сравнить палитру в коде и в Figma.

Название цвета тоже не всегда получается скопировать нормально. Некоторые дизайнеры используют в названии стилей символ «/», но он не поддерживается в iOS и Android. Этот символ нужен, чтобы сгруппировать цвета по группам.

Пример. У цвета в Figma название background/primary. Для Android-разработчиков нужно указать цвет с названием background_primary, а для iOS-разработчиков — backgroundPrimary.

Ещё одна проблема с цветами — темная тема. Ни один инструмент дизайнера (Figma, Zeplin, Sketch) не позволяет иметь темную и светлую палитру одновременно. Тут есть два подхода: создать отдельный файл с темной палитрой либо хранить все цвета в одном файле, но называть их с постфиксом, например, background_primary_day, background_primary_night.

Чего мы хотим как разработчики: чтобы была возможность экспортировать цветовую палитру из Figma напрямую в Xcode или Android Studio проекты.

Проблема #2: неудобный экспорт иконок стандартными средствами

Тут тоже есть несколько затруднений.

Опять же, бывает, что дизайнеры в названии иконок используют символ «/», чтобы группировать иконки. Например, если иконку с названием ic/24/tab/profile экспортировать стандартными средствами Figma, мы получим вот такую вложенность.

С этим невозможно работать. Приходится переименовывать файл. Файл должен называться ic24TabProfile.pdf. Это для iOS-разработчиков.

У Android-разработчиков принято называть ресурсы в стиле snake_case. В таком случае у файла будет название ic_24_tab_profile.xml. Но Figma так не умеет.

Экспортированные из Figma иконки придётся вручную переносить в проект. Причем iOS-разработчикам недостаточно просто перенести их. Надо у каждой иконки проставить: Preserve Vector Data, Single Scale, Render as Template Image.

Чего мы хотим как разработчики: чтобы была возможность экспортировать все иконки из Figma напрямую в Xcode или Android Studio-проекты.

Проблема #3: неудобный экспорт иллюстраций стандартными средствами

Иконки — маленькие векторные изображения, часто черно-белые, они могут перекрашиваться (системой или разработчиком) и изменять свой размер. Если включить accessibility, то некоторые иконки увеличиваются вместе с текстом.

Основная их проблема — названия: символ «/», о котором я говорил выше и то, что iOS-разработчики используют названия в стиле camelCase, а Android разработчики — snake_case.

Иллюстрации — цветные большие изображения, которые отличаются в темной и светлой теме. В темной теме цвета должны быть приглушенными. Если иллюстрация слишком светлая, то выделяясь на темном, она будет «бить» ярким светом в глаза.

С иллюстрациями те же проблемы, что и с иконками, но есть ещё и парочка новых.

Android-разработчики экспортируют иконки и иллюстрации из Figma как SVG-файлы, а затем, встроенными в Android Studio средствами, конвертируют SVG-файлы в vector drawable XML-файлы. Если надо будет экспортировать 50 иконок или иллюстраций, то потребуется много времени, чтобы их все сконвертировать. Это можно автоматизировать.

iOS-разработчики экспортируют иллюстрации как растровые картинки в трех масштабах. Если приложение поддерживает темную тему, то всего будет 6 картинок. Вот так это выглядит в iOS-проекте:

А теперь представим, что из Figma мы выгрузили 50 иллюстраций. Получается, что у нас 50*6=300 PNG-картинок, которые надо вручную через drag&drop перенести в проект, а потом ещё их все, опять же, вручную переименовывать. Хочется ли это делать? — нет. Есть дела поважнее…

Чего мы хотим как разработчики: чтобы была возможность экспортировать все иллюстрации из Figma напрямую в Xcode или Android Studio-проекты.

Почему Zeplin не помог:

  • он не поддерживает темную тему;
  • не позволяет иметь несколько цветов с одинаковым HEX значением, но разными названиями: если называть цвета по месту их применения, то может получиться так, что два цвета будут иметь разные названия, но одинаковые HEX значения. Например, backgroundPrimaryPressed (цвет главного фона при нажатии) и backgroundSecondary (цвет второстепенного фона) должны иметь одинаковые HEX значения. Zeplin не позволит такое сделать. Есть обходной путь — изменить HEX значение на минимально возможную величину. Пример #F4F5F8 и #F4F5F7;
  • требует дополнительные ресурсы дизайнера на синхронизацию макетов и UI-кит с Figma;
  • стоит дополнительных денег. Figma для организации стоит $12 на дизайнера в месяц. Если покупать Zeplin, то это ещё $10.75 на дизайнера в месяц.

Как мы автоматизировали экспорт ресурсов из Figma

Осознав, что так жить больше нельзя, я посмотрел, есть ли у Figma какое-нибудь API или возможность расширения плагинами, чтобы автоматизировать экспорт, и оказалось, что да, есть.

У меня было два пути: написать Figma-плагин или использовать Figma API. Figma-плагин работает непосредственно в приложении Figma. С помощью Figma API можно написать консольную утилиту. Плагин может не только читать информацию из Figma-файлов, но и вносить в них изменения. Из-за этого Figma-плагины требуют, чтобы у разработчика были права на редактирование файла.

Figma API может только читать информацию из Figma-файлов. Плагин пишется на JavaScript. Используя Figma API, можно писать обертку на чем угодно. Но Figma-плагин не может работать с файловой системой на компьютере разработчика (пользователя). Именно поэтому я не стал его делать.

Я iOS-разработчик, поэтому решил сделать консольную утилиту на Swift. Начал с прототипа, который должен экспортировать цветовую палитру из Figma прямо в Xcode-проект. Через пару недель он был готов. Это было нечто. Я запустил свою утилиту и через несколько секунд получил в Xcode всю палитру. Вот так должен работать идеальный экспорт из Figma :)

Спустя пару месяцев моя утилита для экспорта ресурсов из Figma была готова. Ссылку на неё вы можете найти в конце статьи.

Как происходит процесс экспорта

Цвета

Разработчик вызывает команду figma-export colors.

Если это iOS-проект, то цвета экспортируются в папку Assets.xcassets. Дополнительно создается Color.swift-файл, чтобы можно было использовать цвета прямо из кода.

import UIKit extension UIColor { static var backgroundSecondaryError: UIColor { return UIColor(named: #function)! } static var backgroundSecondarySuccess: UIColor { return UIColor(named: #function)! } static var backgroundVideo: UIColor { return UIColor(named: #function)! } ... }

Если это Android-проект, то цвета экспортируются в файл values/colors.xml и values-night/colors.xml, если темная тема поддерживается.

values/colors.xml

<?xml version="1.0" encoding="utf-8"?> <resources> <color name="button">#7701FF</color> <color name="button_ripple">#8A80FF</color> <color name="button_disabled">#D9DCE1</color> <color name="text_primary">#FFFFFC</color> <color name="text_primary_pressed">#A680FE</color> <color name="text_primary_disabled">#FFFFFE</color> <color name="text_secondary">#101828</color> <color name="text_tertiary">#A5ACBD</color>

values-night/colors.xml

<?xml version="1.0" encoding="utf-8"?> <resources> <color name="button">#6F01EC</color> <color name="button_ripple">#7D6AF0</color> <color name="button_disabled">#3F334B</color> <color name="text_primary">#E6D9F6</color> <color name="text_primary_pressed">#E6D9F3</color> <color name="text_primary_disabled">#544761</color> <color name="text_secondary">#E6D9F5</color> <color name="text_tertiary">#7B6F98</color> ...

Иконки

Разработчик вызывает команду figma-export icons.

Если это iOS-проект, то иконки будут экспортированы как PDF-файлы с параметром Render as Template Image, в папку Assets.xcassets. Если иконки будут использоваться вUITabBar, то можно дополнительно указать Preserve Vector Data, чтобы поддерживать Accessibility.

Если это Android-проект, то иконки будут экспортированы в папку drawable как векторные xml-файлы. Под капотом утилита конвертирует SVG-файлы в XML с помощью официальной утилиты vd-tool (vector-drawable-tool), которая используется в Android Studio.

Иллюстрации

Разработчик вызывает команду figma-export images.

Будет все тоже самое, только картинки экспортируются как PNG-файлы.

Если это Android-проект, то иллюстрации будут экспортированы в папку drawable и drawable-night как векторные xml-файлы.

Как можно настроить экспорт

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

./figma-export colors -i figma-export.yaml

В конфигурационном файле указываются параметры для iOS, для Android и общие параметры. Также там указывается идентификатор Figma-файла, где расположены цвета, иконки и картинки.

Идентификатор файла можно найти в адресной строке, если открыть его в браузере.Вот, например, адрес нашего UI Kit: www.figma.com/file/GVHjNNE8PKKRf1KtnMPY9m/RTC-Key-UI-kit

Идентификатор файла lightFileId в нашем случае: GVHjNNE8PKKRf1KtnMPY9m

Пример конфигурационного файла для iOS-проекта:

--- figma: lightFileId: shPilWnVdJfo10YFo12345 darkFileId: KfF6DnJTWHGZzC9Nm12345 ios: # Path to the Assets.xcassets directory xcassetsPath: "./Resources/Assets.xcassets" # Parameters for exporting colors colors: # Should be generate color assets instead of pure swift code useColorAssets: True # Name of the folder inside Assets.xcassets where to place colors (.colorset directories) assetsFolder: Colors # Path to Color.swift file where to export colors for accessing colors from the code (e.g. UIColor.backgroundPrimary) colorSwift: "./Sources/Presentation/Common/Color.swift" # Color name style: camelCase or snake_case nameStyle: camelCase # Parameters for exporting icons icons: # Name of the folder inside Assets.xcassets where to place icons (.imageset directories) assetsFolder: Icons # Icon name style: camelCase or snake_case nameStyle: camelCase # [optional] Enable Preserve Vector Data for specified icons preservesVectorRepresentation: - ic24TabMain - ic24TabHistory - ic24TabProfile # Parameters for exporting images images: # Name of the folder inside Assets.xcassets where to place images (.imageset directories) assetsFolder: Illustrations # Image name style: camelCase or snake_case nameStyle: camelCase

Пример конфигурационного файла для Android-проекта:

--- figma: lightFileId: shPilWnVdJfo10YFo12345 darkFileId: KfF6DnJTWHGZzC9Nm12345 android: mainRes: "./main/res"

Как организовать Figma-файл для автоматизированного экспорта ресурсов

Чтобы UI-Kit можно было автоматизированно выгрузить необходимо соблюдать следующие правила.

Общие

  • Если цвет, иконка или иллюстрация уникальны для iOS или Android у неё в свойствах, в поле description должно быть указано “ios” или “android”. Если цвет, иконка или иллюстрация не должны быть доступны для экспорта, то у них в свойстве description будет “none”. Таким образом FigmaExport определит, что надо экспортировать в iOS-проект, что в Android проект, а что вообще не надо экспортировать.

Пример. В iOS и Android иконка «поделиться» выглядит по-разному. На скриншотах ниже указано, что иконка ic24ShareIos будет экспортирована только в iOS-проект т.к. в свойстве Component description указано ios, а иконка ic24ShareAndroid будет экспортирована только в Android-проект;

  • Иконки и иллюстрации должны быть компонентами;
  • Цветовые стили и компоненты должны быть опубликованы в Team Library;
  • Экспортируются только те иконки и иллюстрации, которые добавлены во фреймы Icons и Illustrations.

Примеры.

Названия ресурсов

Цвета, иконки и иллюстрации можно называть любыми именами содержащими буквы a-z, A-Z и символы «_» и «/».

Так как в коде названия переменных не могут иметь символ “/”, FigmaExport автоматически заменяет его на символ «_». Далее полученная строка конвертируется в camelCase для iOS либо в snake_case для Android.

Для консистентности и удобства можно, например, называть все иконки в своем формате — ic/размер/название. Пример — ic/24/open. А иллюстрации — img/группа/название. Пример — img/zero/nointernet. Про цвета дизайн-команда рассказывала в статье «Дизайнеру приложений: как создать и передать в разработку тёмную тему».

В конфигурационном файле figma-export.yaml можно с помощью регулярных выражений включить валидацию названий перед экспортом. Если какой-либо ресурс будет иметь неправильное название, FigmaExport сообщит об этом.

common: colors: # RegExp pattern for color name validation before exporting nameValidateRegexp: '^[a-zA-Z_]+$' # RegExp pattern for: background, background_primary, widget_primary_background icons: # RegExp pattern for icon name validation before exporting nameValidateRegexp: '^(ic)_(\d\d)_([a-z0-9_]+)$' # RegExp pattern for: ic_24_icon_name, ic_24_icon images: # RegExp pattern for image name validation before exporting nameValidateRegexp: '^(img)_([a-z0-9_]+)$' # RegExp pattern for: img_image_name

Темная тема

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

Цвета

В Figma-файле цвета должны быть оформлены как цветовые стили и опубликованы в Team Library. Для удобства разработчиков желательно сделать таблицу всех цветов, где будет указано, какой цвет и где используется.

Иконки

В Figma-файле должен быть Frame с именем Icons. В этом Frame должны находиться компоненты для каждой иконки. Пример:

Иллюстрации

В Figma-файле должен быть Frame с именем Illustrations, который содержит компоненты для каждой иллюстрации. Пример:

Итог

Благодаря FigmaExport мы избавились от множества проблем при работе с Figma. Экспорт ресурсов теперь занимает секунды. Несколько примеров, как нам облегчило жизнь использование утилиты.

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

Как бы мы их обновляли вручную: экспортировали все иконки из Figma как zip-файл, переименовали 52 файла, перенесли иконки в проект, проставили все необходимые свойства, проверили, что ничего не забыли. На это бы ушло не менее часа времени.

Как мы их обновили c FigmaExport: запустили команду figma-export icons. Через 10 секунд все изменения подтянулись, мы запустили приложение на симуляторе и увидели, что все иконки заменились.

2. На одном из спринтов мы решили сделать новую фичу. В UI-Kit дизайнер добавил четыре новые иконки, удалил две старые иконки, добавил два новых цвета.

Вместо того чтобы потратить один час времени на обсуждение с дизайнером, что он изменил в UI-Kit, ручном экспорте иконок и цветов, мы просто запустили команду figma-export colors и figma-export icons и через Git увидели что удалилось, что добавилось, а что изменилось. Сразу стали верстать макеты, используя новые иконки и цвета.

3. Делали фичу, в которой надо было сделать расширенный онбординг с 4 разделами, в каждом из которых до 7 страниц с картинками.

Ручной экспорт занял бы много времени. Выполнив команду figma-export images мы менее, чем за минуту, получили в проекте все эти картинки, готовые к использованию.

Несколько минусов

  • Необходимо договариваться с дизайнером о том, как надо хранить цвета, иконки, картинки в UI-Kit, чтобы их можно было автоматизировано выгрузить.
  • Экспорт работает только для тех компонентов, которые добавлены в Team Library, поэтому у дизайнеров должна быть платная подписка на Figma.

Планы:

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

Ссылка на утилиту

Буду рад, если вы попробуете мою утилиту. Вопросы, пожелания, фидбек — пишите мне на [email protected]

Даниил Субботин
ведущий разработчик iOS Redmadrobot
0
6 комментариев
Написать комментарий...
Антон Кокорев

Красавчики! Дизайн приложений давно стал своего рода "программированием" и требует аналогичных подходов. Молодцы что двигаетесь в этом направлении.

Ответить
Развернуть ветку
red_mad_robot
Автор

Антон, спасибо)

Ответить
Развернуть ветку
Deniss Karpak

Круто, скачал. Спасибо

Ответить
Развернуть ветку
Софья Старикова

Здорово, очень вдохновляет!

Ответить
Развернуть ветку
Damir Rashidullin

Прекрасная статья, помогла понять некоторые взаимосвязи с разработчиком! От души

Ответить
Развернуть ветку
Павел Железняк

Каждый раз вместо Фигма читаю Фигня.

Ответить
Развернуть ветку
Читать все 6 комментариев
null