Перенести банковское приложение на Flutter в одиночку и сохранить свои нервы: миссия невыполнима?
Дмитрий, Flutter-разработчик DexSys, в кроссплатформенной мобильной разработке уже больше 3х лет. В этой статье расскажем, как он переносил функционал банковского приложения с нативного на кроссплатформу, поделимся проблемами, вставшими на пути, и заглянем внутрь проекта «Мобильный банкир». Передаем слово Диме:)
«Пара слов о продукте:
Мобильный банкир — это система дистанционного обслуживания клиентов. Позволяет отслеживать заявки на доставку банковских продуктов или документации.
МБ работает на двух платформах:
- Мобильное приложение для сотрудников или партнёров банка — обеспечивает процесс доставки.
- Web-приложение, в котором можно настроить систему и мониторить доставку.
Команда проекта: 1 product owner, 2 системных аналитика, 3 back-разработчика, 1 front-end разработчик, 1 iOS/Android разработчик, 2 тестировщика, 1 flutter-разработчик, 1 собственный специалист поддержки пользователей.
Зачем нужна кроссплатформа?
Бизнес-заказчик дал нашей команде задачу не увеличивая количество человек уменьшить время на реализацию и выпуск идей/обновлений.
Технический лид проекта увидел во Flutter-е возможность для увеличения скорости разработки. Сначала команда проверила эту гипотезу на разработке зарплатного проекта для внешних агентов банка. Далее, с помощью разработчика Flutter начали выравнивать сроки разработки для Web-версии и мобильного приложения.
Так что же такое Flutter, и с чем его едят?
Flutter уверенно занимает ТОП-1 в кроссплатформенных языках. Он сокращает время на разработку, и, соответственно, на доставление продукта конечному пользователю. Если говорить бизнесовым языком, то «скорость выше и платишь меньше».
Едят Flutter вместе с языком Dart. На вкус такой же аппетитный, как и JavaScript.
Начав писать на Flutter, можно прочувствовать на себе следующие моменты:
- Нервные клетки исчезают гораздо реже;
- Появляется больше свободного времени;
- Повышается самооценка:)
Чуть больше деталей:
- Под капотом свой графический движок Skia и рантайм Dart VM. Написано на C/C++. Соответственно, запускать код ты можешь прямо из консоли, без всяких IDE`шек;
- Очень хорошо поддерживаются 2 платформы – iOS/Android, чуть меньше – WEB, и потихоньку встает на ноги поддержка MacOS/Windows/Linux.
Как переводил? С чего начинал?
Я пришел на проект, когда нативные версии были в проде уже более 5-ти лет. А flutter-копия только училась ходить — был написан функционал одной роли. Всего в приложении их три:
- Курьеры: доставляют банковские продукты
- Кредитные специалисты на административных пунктах и сотрудники в банковских отделениях - осуществляют выдачу дистанционно одобренных продуктов
Архитектура:
Изначально я хотел переписать всё на BLoC, так как это чистая и всеспособная архитектура. Но любовь к трудностям победила — я решил оставить текущую реализацию, MobX.
Для начала я отрефакторил структуру папок, переписал некоторый код для лучшей производительности и приступил к двухфакторке. Она необходима для верификации пользователя и для нее используются стандартные http запросы.
И тут случился первый фейл - когда двухфакторная верификация уже была переписана, разработчики в команде решили перейти на gRPC.
Привести мысли в порядок помогли размышления о том, что у Flutter большое растущее комьюнити и наверняка для grpc-запросов уже есть готовые библиотеки. И я не ошибся! Мои нервные клетки сохранились:)
Но ненадолго… Вскоре после переписывания функционала, в связи с безопасностью тестовых сред, grpc-запросы отменили. Пришлось откатывать все обратно до http-запросов.
Но ненадолго… Вскоре после переписывания функционала, в связи с безопасностью тестовых сред, grpc-запросы отменили. Пришлось откатывать все обратно до http-запросов.
Функционал ролей
Если вам когда-либо потребуется работать с распределением ролей, рекомендую использовать абстракцию. Благодаря ей:
- сильно сокращается время багофиксов и изменений;
- один элемент может использоваться в 5-ти местах, не нарушая функциональность каждого из них
Но продумать такую абстракцию за раз невозможно, поэтому лучше привести виджеты к универсальному виду, так как они могут понадобиться в новых ролях. А если это невозможно, то поделить на разные виджеты. Ведь универсальность — это, конечно, хорошо, но и чистоту кода нужно сохранять.
Решением стал MobX. На нём можно сделать «обозреваемый геттер», который будет смотреть и следить за заданными условиями. Если условие поменялось – геттер сразу его подхватит и обновит информацию. Так мы оставляем чистый код и не переносим все условия на UI.
Перенос функционала курьеров:
В приложении курьеру нужно иметь карту с пакетами и список пакетов и договоров на доставку. По каждому договору нужны:
- Детальная информация
- Договоренности
- Реквизиты новой карты
- Печатные документы
- Фото клиента
- Фото залога и чек-листа
- Фото основного пакета документов
Расскажу подробнее о некоторых пунктах:
Реквизиты:
На этом этапе реализовали для курьеров возможность ввести банковский счет, где мы используем overlay.
Печатные материалы:
У dart’а есть возможность запускать ссылки. Просто вставляешь в метод (launchUrl) диплинк для почты и вуаля: для того, чтобы отправить печатные материалы на почту, нужно нажать всего одну большую кнопку по центру экрана – трудно промахнуться.
Фото клиента/залога/документов:
Этот функционал используется для идентификации клиента. Основная задача заключалась в том, чтобы сделать единую, но при этом адаптивную схему фотографирования, так как UI и техническая часть не везде одинаковые. Также у самих фотопакетов могли различаться состояния.
Решение: Разграничили state на следующие части: у каждого фотопакета есть своя view model с одинаковой структурой, у каждого сегмента/формы — отдельный state, в котором хранится основная информация по сегменту/форме + специфическое взаимодействие с сервером.
Таким образом, мы получаем примерно такую структуру:
PackageDetails -> ClientPhotoSegment -> ClientPhotoStore -> ClientPhotoVM.
Также, в приложении «Мобильного банкира» есть функционал обращений. Каждый из пользователей приложения может задать любой интересующий вопрос тех. поддержке, скорость ответа на который особенно важна для выездных курьеров. В переписке должна быть реализована возможность выбрать готовые темплейты, помогающие быстрее получить ответ, и, для того чтобы UI не выглядел деревянно,— нужно была анимация.
Решение: за ним далеко идти было не нужно, т.к. из коробки Flutter у нас уже есть подходящий SliverAnimatedListView
Что в итоге?
Убедившись в положительном результате, за 11 месяцев мы переписали все функциональные блоки приложения, которые команда писала на нативных приложениях с 2016 года, и, несмотря на сложности в процессе переноса, скорость разработки оказалась в 2 раза выше чем у нативных версий, а нервные клетки команды стали исчезать гораздо реже.
Таким образом, мы освободили еще и ресурс тестировщика — теперь не нужно тестировать две платформы. Появилось время на автотестирование и улучшение процессов.
Быть единственным разработчиком на проекте, конечно, классно, но порой мне не хватало еще одного разраба, на которого можно было скинуть пару задачек и спокойно пойти изучать что-то новое. Благо, сейчас время есть, и, в скором времени, проект «Мобильный Банкир» в очередной раз улучшится.
Рекомендации всем, кто хотел бы вникнуть во Flutter:
1) Очень советую пробежаться по официальной документации, ибо она написана какими-то невероятными гениями.
2) Можно глянуть ютуб канал разработчиков.
3) Ну и напоследок: чистая архитектура + BLoC понятным языком»