Добро пожаловать в MVVM-маршрутизатор с SwiftUI и Combine

Многообещающая ViewModel

Всем привет. Как и многие из вас, я недавно начал свое путешествие в новый и странный мир SwiftUI и Combine, и должен сказать, что по большей части мне очень нравится поездка. Да, конечно, он новый, яркий и молодой, но он также полон обещаний (объединить, подмигнуть). Я очень надеюсь, что эти инструменты хорошо созреют и наберут достаточную динамику, чтобы оставаться для нас, разработчиков iOS.

Но не будем отвлекаться, а сосредоточимся на цели этой статьи. Как и в случае с любыми новыми инструментами, требуется несколько проб и ошибок, чтобы выяснить, как лучше всего их использовать и извлечь из них максимальную пользу. С большой мощностью приходит и великая… (шепот на ухо говорит мне, что я на правильном пути).

В этой статье вы найдете мой взгляд на реализацию SwiftUI и Combine в MVVM в очень простом проекте.

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

Но меньше разговоров и больше отображения кода.

Образец проекта

Как упоминалось ранее, проект, созданный для этой статьи, очень упрощен.

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

Исходный код можно найти здесь: SpaceXSwiftUICombine.

См. также:  dyld: Библиотека не загружена: @ rpath / Alamofire.framework / Alamofire и AlamofireImage

Основная цель — показать пользователю все запуски SpaceX, добавив при этом несколько небольших функций обработки данных (поиск и фильтр).

Вот что вы можете найти, покопавшись в исходном коде:

  • Объединить сети
  • Единый источник достоверных данных (комбинация инструментов Combine / внедрение зависимостей)
  • Координатор централизованной маршрутизации
  • Множество инъекций зависимостей
  • Множество протоколов: 0
  • Некоторые функции поиска и фильтрации

Но в целом структура ядра должна выглядеть очень похожей на предыдущие реализации MVVM, с которыми вы, возможно, уже знакомы.

Основная особенность этого MVVM-роутера

Координатор централизованной маршрутизации

Если вы уже немного работали со SwiftUI, вы, должно быть, очень рано заметили, что представления очень тесно связаны друг с другом. Ссылки или листы навигации обычно вызывают следующее представление в потоке навигации по имени. Это делает любые будущие изменения в навигации очень сложными (особенно в сложной среде навигации приложений). Мой подход заключался в том, чтобы попытаться централизовать маршрутизацию в одном месте, которое может быть совместно использовано или передано любой модели представления.

Как вы можете видеть в приведенном выше коде, mainRouter основан на протоколах, которые помогают разделять представления. Это можно сделать, установив маршрутизатор в модели представления и вызвав его при необходимости в представлении, как показано в следующих двух примерах.


И вуаля, ваше представление не обращает внимания на то, что представляет routeToLaunches () или routeToRockets ().

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

Единый источник достоверных данных

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

Это не ново, но работает хорошо.

Как и в случае с протоколами маршрутизации, мы используем возможности протоколов для уменьшения связи. Репозиторий может быть передан путем внедрения зависимостей в любую часть приложения. Просто подпишитесь на издателей, указанных в протоколе, и у вас будет доступ к последнему и самому свежему потоку данных.

См. также:  Обновите мир Minecraft с модом Aliens vs. Predator 1.12.2–1.10.2

Примеры стоят тысячи слов:

  1. Объявите свой репозиторий для обмена данными
  2. Ввести компонент
  3. Подпишитесь и назначьте или используйте отправленные данные. Очень хорошо работает в сочетании с переменной @Published.
  4. Затем вы можете применить к данным требуемые преобразования.
  5. Примените эти изменения к локальным данным по своему желанию.

В целом, реализовать эти типы методов с помощью SwiftUI, Combine и какого-то DI несложно. Если вам лень, существует множество библиотек внедрения зависимостей, которые должны помочь (Resolve, SwiftInject и т. Д.).

Легкость обработки данных

В качестве последнего указателя я хотел бы быстро перейти к прекрасному симбиозу, который уже существует между SwiftUI и Combine.

Для этого вы просто собираетесь сосредоточиться на реализации очень простой панели поиска и фильтров.

Выше показан простой вид сетки, отображающий запуски пространства X.

  1. Связывание между представлением и viewModel. В этом случае содержимое TextField и переменная запроса viewModel.
  2. Связывание между представлением и фильтром viewModel.
  3. Связывание отображаемых данных Gridview с запуском viewModel.

Далее давайте посмотрим, как обрабатывать входящие данные в viewModel.

Волшебство происходит в переменной filterLaunchesPublisher. Комбинируйте, устраняйте, обрабатывайте и назначайте. В очень небольшом количестве строк кода у нас есть полностью функциональный поиск и фильтрация наших данных.

  1. @ Опубликованные переменные, помогающие связывать данные между viewModel и представлением.
  2. Создание паблишера для обработки данных. В данном случае это комбинация нашего основного потока правды: запусков, запроса и примененного фильтра.
  3. Назначьте издателя обработки локальной ограниченной переменной для отображения актуальных данных.

Несколько советов и приемов, которые стоит попробовать

Я завершу эту статью несколькими советами и приемами, которые я усвоил во время работы со SwiftUI и Combine.

Назначить сильную ссылку

Во-первых, кажется, что комбинация assign создает сильную ссылку между элементами. Чтобы решить эту проблему, кто-то на forum.swift.org придумал небольшой симпатичный фрагмент кода. Я бы предложил использовать это.

См. также:  То же самое можно сказать и о React: «Поместить HTML в JS - безумие!».

Еще одна странная находка заключается в том, что представление, установленное в пункте назначения NavigationLink, не всегда загружается лениво. На самом деле кажется, что все совсем наоборот. Это может привести к тому, что ваше приложение будет загружать огромные объемы данных при запуске. И снова StackOverflow — наш друг. И один из наших коллег придумал красивый небольшой фрагмент кода, чтобы обойти эту проблему. Более подробную информацию можно найти здесь. Уловка заключается в следующем:

Затем вы используете его так:

NavigationLink(destination: LazyView( ** Put your destination view **)) { ** NavigationLink UI ** }

Надеюсь, этот небольшой обзор того, как можно реализовать MVVM с помощью SwiftUI и Combine, помог вам. Я надеюсь, что он дал вам несколько хороших идей и прояснил все ваши вопросы.

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

Понравилась статья? Поделиться с друзьями:
IT Шеф
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: