Что учесть при разработке мобильного Flutter-приложения: чек-лист
Flutter — кроссплатформенный UI-фреймворк для разработки мобильных приложений, написанный на языке программирования Dart. Его главное преимущество — пишешь код один раз, а затем компилируешь для Android, iOS, десктопа и других платформ. Экономит уйму времени и ресурсов.
Если есть небольшой опыт программирования, начать писать на Flutter легко:
1. Зайдите на docs.flutter.dev.
2. Установите окружение и инструменты по инструкции.
3. Выберите удобную среду разработки — чаще всего Android Studio или VS Code.
4. Создайте проект — и вот базовое приложение готово.
Разобраться в нюансах написания кода на Flutter поможет архив лекций открытого лектория от Летних школ Академии Яндекса, который прошёл в 2022 году. После просмотра ваше приложение обзаведётся новыми фичами, работой с сервером, хранилищем, архитектурой.
Если совсем незнакомы с технологией, советую прочесть статью Ильи Вирника «Зачем учиться разработке на Flutter» и посмотреть мою вводную лекцию открытого лектория в Школе мобильной разработки Академии Яндекса.
Сергей Кольцов, руководитель группы Flutter-разработки в Яндексе
✅ Качество кода
Важно, чтобы код было легко читать, сопровождать, поддерживать и изменять. Есть набор инструментов, которые позволяют быстро и эффективно повысить качество кода:
— Dart format автоматически форматирует код по рекомендациям стиля. Соблюдать их, особенно в команде, необходимо, иначе разработка превратится в бесконечные споры о правильных переносах и языковых конструкциях. Для использования установите Flutter и выполните команду dart format.
— Линтер автоматически анализирует код, помогает найти нарушения стиля и логические ошибки. Лучше увидеть пустое тело в условной конструкции в момент написания кода, чем на тестировании. В каждый Flutter-проект линтер подключён по умолчанию, проверку выполняют командой flutter analyze. Детальная настройка правил — в файле analysis_options.yaml.
— Dart Language Tour и Effective Dart — набор практик и рекомендаций, как писать Dart-код. Обязательно прочитайте правила сами и покажите коллегам: это поможет улучшить код и увидеть потенциальные ошибки на код-ревью.
✅ Сборка
Подготовка релизной и дебажной сборки Flutter-приложения — тоже важные этапы. Релизную сборку используют, чтобы распространить приложение пользователям, дебажную — для тестирования и отладки. Релизная сборка отличается от дебажной двумя важными особенностями:
1. Подписи и сертификаты. Их настройка на Android и IOS занимает время, поэтому не стоит откладывать это на момент перед релизом. Хорошо, что её делают только один раз и в дальнейшем минимально поддерживают.
2. Технические характеристики. Релизная сборка содержит меньше отладочной информации и оптимизирована для более быстрой работы. Чем дольше вы разрабатываете приложение только в дебажном режиме, тем больше вероятность, что, собрав его, обнаружите технические расхождения.
✅ Окружение
Важно на старте подумать о подготовке окружения Flutter-проекта, чтобы сократить время на рутинные операции по настройке проекта для разработчиков.
Подготовьте init-скрипт в репозитории для настройки проекта. Это автоматизирует рутинные операции: инициализацию гитхуков, установку внешних зависимостей или конфигурацию особых параметров среды разработки. Например, вы можете подготовить гитхук, который будет срабатывать каждый раз, когда вы пушите код на сервер, а в init-скрипт добавить код, который поменяет стандартный путь до гитхуков на директорию с вашими:
Ваши гитхуки должны лежать в директории .githooks
git config --local core.hooksPath .githooks/
chmod +x .githooks/pre-push
Настройте Flutter Version Manager (FVM), который управляет установленными версиями Flutter и легко переключается между ними. Если вы работаете над разными Flutter-проектами, то потенциально каждый из них может использовать другие версии Flutter, часто несовместимые между собой. В такой ситуации в каждом проекте настраивают FVM и полностью изолируют окружение проектов друг от друга.
Подготовьте скрипт для каждой дебажной сборки. Он должен быть быстрым и легковесным, чтобы без задержек проверить актуальность окружения проекта. Например, если в основной ветке проекта обновилась версия FVM, скрипт на сборке может подсветить расхождение версий либо самостоятельно выполнить обновление.
Сделать скрипт кодогенерации. В базовом виде команда для кодогенерации выглядит так: flutter pub run build_runner build.
Работать с секретами. Это значения проекта, которые нельзя хранить в репозитории: API-ключи и токены внешних сервисов, релизные подписи и сертификаты, ключи от них. Для работы локально секреты хранят в файлах, которые игнорируются в репозитории в .gitignore. Так секреты не попадают в репозиторий и недоступны публично.
✅ CI/CD
CI (Continuous Integration) — процесс, в котором новый код автоматически собирается и тестируется. Это позволяет разработчикам обнаружить ошибки и баги раньше, чем их найдут на ручном тестировании.
CD (Continuous Deployment) — процесс, где приложение автоматически распространяется на пользователей после успешной сборки и тестирования.
Настройка CI/CD помогает автоматизировать рутинные операции проверок, тестов и сборок. Также CI/CD минимизирует влияние человеческого фактора: всю работу выполняют прописанные алгоритмы. Большинство систем CI/CD поддерживают Flutter. Для старта можно попробовать:
Например, чтобы проверить и собрать релизную Android-сборку и показать её тестировщикам, нужно:
1. Проверить, что код корректно отформатирован с помощью форматтера.
2. Проверить, что в коде нет ошибок, найденных линтером.
3. Выполнить кодогенерацию или проверить, что она актуальна после изменений.
4. Проверить, что успешно проходят все автотесты.
5. Выполнить команду сборки flutter build apk --release.
6. Взять получившийся apk-файл из директории build/app/outputs/flutter-apk и прислать его тестировщику.Каждый из этих шагов занимает от нескольких секунд до десятков минут. В iOS-сборке таких шагов больше, а работа с секретами в разы сложнее и кропотливее. Поэтому лучше выделить один раз время на настройку CI/CD — и дальше всю работу будет делать машина, пока вы попиваете чай.
Сергей Кольцов, руководитель группы Flutter-разработки в Яндексе
✅ Логирование
Позволяет разработчикам отслеживать исполнение программы, идентифицировать и отлаживать ошибки и централизованно настраивать отображение и вывод логов. Логи могут стать хорошей альтернативой комментариям, объясняя происходящее в вашем коде. Базовая информация о логировании во Flutter есть в документации. Кроме того, вот хорошие практики.
Избегайте использования встроенной функции print. Она полезна для быстрой отладки, но print не позволяет настроить уровни логирования, тегировать сообщения, перенаправлять вывод в файл или на сервер. Поэтому лучше использовать специализированные библиотеки логирования: logger, logging или другие.
Настраивайте уровни отображения логов. Это способ фильтрации сообщений по уровню. Обычно существует несколько уровней: например, debug, info, warning, error или их вариации. Их настройка позволяет сфокусироваться на определённых типах сообщений, например на ошибках, и игнорировать остальные.
Не пишите в логи персональные данные пользователей в production-сборках. Это не только неэтично, но и нарушает законы о защите персональных данных.
Тегируйте логи или используйте дерево логгеров на основе имени проекта, чтобы лучше их организовать и упростить анализ. Например, логи помечают тегом модуля, слоя приложения или фичи. Это позволяет быстро найти нужные сообщения в логах и проанализировать их.
Пример создания логгера с помощью пакета logging и его использования:
✅ Обработка ошибок
Заранее подумайте о двух ситуациях.
Ошибка ожидаема, и вы знаете, как её обрабатывать. Например, ошибка сервера, когда нужно повторить запрос. Или проблема получения данных из плагина — тогда нужно показать экран с ошибкой. Такие ошибки обрабатывают через try-catch: явно указывают тип ошибки и описывают поведение, в случае их возникновения.
Ошибка не ожидаема, и вы не знаете, как вести себя в коде, если она случилась. Их нельзя «замалчивать», делая try-catch и оставляя catch-блок пустым. Так вы усложните себе жизнь: ни в логах, ни в аналитике информации не будет. Их правильнее оставить необработанными (unhandled или uncaught), не делая try-catch, и дать фреймворку поймать их для централизованной обработки.
Поймав ошибки, вы можете выводить их в лог, отправлять в аналитические сервисы, записывать в файл и даже намеренно закрэшить приложение, если это необходимо.
✅ Интернационализация
Это подготовка приложения к переводу на разные языки. Если интернационализация не учтена в начале разработки, перевод приложения на другой язык будет трудоёмкой задачей. Например, без неё все строки в приложении используют напрямую в коде, их поиск и переписывание на переменные потребует кропотливого и рутинного труда.
Во Flutter-приложении интернационализацию реализуют несколькими способами:
1. С помощью пакета flutter_localizations, который поставляется вместе с Flutter SDK.
2. Более расширенный вариант — с помощью пакета intl.
3. Через сторонние библиотеки.
✅ Тема и дизайн
Выделяют два способа управления темой во Flutter-приложении, причём они не взаимоисключающие. Для разных ситуаций подходят разные способы:
— Централизованная тема для всего приложения позволяет управлять цветами, шрифтами и другими стилевыми элементами во всём приложении из одного места. Чтобы её использовать, нужно создать экземпляр класса ThemeData и задать параметры: цвета, шрифты и размеры для стандартных виджетов. Затем экземпляр вашей ThemeData вы передаёте в MaterialApp в аргумент theme — с этого момента все виджеты внутри MaterialApp будут использовать указанную тему.
— Отдельные UI-компоненты. Вы можете создать отдельные универсальные виджеты (кнопки, поля для ввода, блоки с данными) с помощью Stateless- и Stateful-виджетов. Внутри них — описать стилистические характеристики и конкретизировать формат конфигурации компонента. Например, ограничить набор параметров или добавить собственные. Каждый виджет станет единой точкой изменения внешнего вида. Остальное приложение будет пользоваться им, не вдаваясь в детали реализации.
✅ Иконка
Для подготовки иконки есть несколько простых вариантов:
— Библиотека flutter_launcher_icons.
— Встроенный генератор в Android Studio.
— Онлайн-генераторы.
Это важная деталь, которую большинство откладывает на потом. Иконка — это первое впечатление, она с самого начала вызывает эмоции у пользователей и всей команды разработки.