+7 (3412) 56-18-05
hr@dexsys.ru
г. Ижевск, ул. Удмуртская, 304, торгово-офисный
центр «Аврора Парк»
«Dexsys», 2012-2023
2 февраля 2023

Перенести банковское приложение на Flutter в одиночку и сохранить свои нервы: миссия невыполнима?

Дмитрий, Flutter-разработчик DexSys, в кроссплатформенной мобильной разработке уже больше 3х лет. В этой статье расскажем, как он переносил функционал банковского приложения с нативного на кроссплатформу, поделимся проблемами, вставшими на пути, и заглянем внутрь проекта «Мобильный банкир». Передаем слово Диме:)
«Пара слов о продукте:
Мобильный банкир — это система дистанционного обслуживания клиентов. Позволяет отслеживать заявки на доставку банковских продуктов или документации.

МБ работает на двух платформах:
  1. Мобильное приложение для сотрудников или партнёров банка — обеспечивает процесс доставки.
  2. 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-запросов.
          Функционал ролей
          Если вам когда-либо потребуется работать с распределением ролей, рекомендую использовать абстракцию. Благодаря ей:

          • сильно сокращается время багофиксов и изменений;
          • один элемент может использоваться в 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 понятным языком»

              Автор статьи: Дмитрий, Flutter-разработчик DexSys.
                «Dexsys», 2012-2023
                г. Ижевск, ул. Удмуртская, 304,
                торгово-офисный центр «Аврора Парк»
                +7 (3412) 56-18-05
                hr@dexsys.ru