Connect with us

Программирование

Flow Engine — движок iOS-навигации в Revolut

По сути, как следует из названия, это механизм (конечный автомат) для обработки потока (набора шагов).

Опубликовано

/

     
     

Вы когда-нибудь слышали о шаблоне Координатор? Отлично, потому что статья не о нем. Я здесь, чтобы рассказать вам про кастомный движок навигации, наш Revolut Flow Engine.

Сначала давайте поговорим о некоторых традиционных подходах к навигации.

Навигация в экшенах Storyboard-а

Flow Engine - движок iOS-навигации в Revolut

Самый традиционный способ навигации с помощью сторибордов — это тот, который запускается действием. Вы можете нажать Ctrl и перетащить кнопку на другой View, чтобы перейти к нужному экрану.

Навигация в переходах

Flow Engine - движок iOS-навигации в Revolut

Другим традиционным типом навигации в сторибордах являются Segue (переходы). Нажав Ctrl можно перетащить  один контроллер представления к другому. Так создается соединение определенного типа (push, модальное и т.д.) и присваивается ему идентификатор.

performSegue(withIdentifier: "firstScreenToThirdScreenSegue", sender: nil)

Навигация, управляемая кодом в ViewController

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

Движок Flow

Теперь давайте вытащим большую пушку: абстракцию навигации вне контроллеров представлений.

Зачем нам абстрактная навигация? Что ж, представьте, что у вас есть приложение для доставки еды FoodDeliveryApp, и там у вас есть экран под названием ProductDetails, который показывает информацию для данного продукта (гамбургер 🍔, рыба с жареным картофелем 🍟 и т.д.), но вы хотите вызывать этот экран и его зависимости из любого места. Будет ли лучше везде создавать экземпляр экрана с его зависимостями и действиями? Конечно нет!

Не волнуйтесь, сейчас все поймете. Вот код:

Мы создаем ProductDetails View Controller со всеми значениями и действиями, управляемыми через его модель представления. Здесь мы видим, что бизнес-действия модели представления делегируются посредством внедрения зависимостей.

Когда мы хотим вызвать наш экран ProductDetail и передать его бизнес-действия через внедрение зависимостей, мы в конечном итоге делаем это:

Код кажется вам чистым? Ну, почти 😅 Что происходит, когда вам нужно показать эту страницу продукта из других контроллеров представления и обработать ее действия? .showRelatedProduct и .addToOrder? Скопировать и вставить эту реализацию? 😢 Плохо!

Что, если бы вы могли абстрагироваться от этого и просто вызвать какой-то магический метод? Скажем, runProductDetailsFlow(productId:_) с экшенами и зависимостями этого экрана, абстрагированными на этом уровне? Ну и без лишних слов

Flow Engine - движок iOS-навигации в Revolut

По сути, как следует из названия, это механизм (конечный автомат) для обработки потока (набора шагов). Тщательно продуманная конечная машина, созданная нашей легендой Revolut Ильей Велиляевым. Начнем с его основы:

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

С FlowEngine (не стесняйтесь копипастить этот файл и использовать его для создания отличных потоков в своих приложениях 🚀) вы можете создавать потоки для различных бизнес-кейсов. Давайте вернемся к нашему примеру с приложением доставки еды и создадим поток для отображения ProductDetail с его зависимостями и абстрагированными бизнес-действиями! 🎉

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

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

Этот Flow Performer выполняет каждый шаг, определенный в вашем потоке, и позволяет вам предоставить для него код. Обратите внимание, как мы используем еще не определенный FlowRunner.

Когда у вас есть FlowPerformer, вы можете приступить к созданию своего волшебства в FlowRunner — это он позволяет делать навигацию в одну строчку flowRunner.runProductDetailFlow(…):

FlowRunner позволяет запускать любой бизнес-поток со всеми его зависимостями и абстрагированными бизнес-действиями.

Теперь из любого места вашего кода (наиболее предпочтительно из других потоков) вы можете вызывать любое количество потоков, избегая при этом дублирования кода и используя более простой TDD подход к своему коду.

Вот и все, надеюсь, вам понравилось и вы начали контролировать, тестировать и абстрагировать навигацию в своих приложениях 🚀

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Advertisement

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: