SwiftUI — Model View Intent (MVI)

Siamak (Ash) Ashrafi
4 min readNov 26, 2019

SwiftUI + Combine Framework (State) = MVI & Android Jetpack Compose / Kotlin Flow should also use it!

Sorry, I will not explain what MVI is. I will leave that as an exercise for the student … Wow, I hated when my professors do that!!!

Model View Intent (MVI) is a reactive architectural pattern where the model is updated based on intents of the user/system and the view is updated based on states emitted from the model.

MVI is: 1) Unidirectional Data Flow, 2) Immutable State, 3) Single Entry / Exit, 4) Reactive & Functional

MVI declarative programming it is better than MVC, MVP, MVVM and VIPER

  • Model View Controller (MVC) — Do not use MVC because it is hard to test.
  • Model View Presenter (MVP) — Do not use MVP although testable it does not do live updates.
  • Model View View Model (MVVM) — Do not use MVVM although testable and does live updates it relies on two way data binding not unidirectional reactive streams (leads to inconsistent results depending on the amount of asynchronous processing).
  • VIPER (View Presenter Interactor Entity Routing) — Do not use VIPER … Overly complex and mostly used for iOS

Use MVI! It is the best of all the current mobile architectures.

Fact: MVI solves many issues by making models represent a state rather than data. And view is a function of that state (single source of truth) not a sequence of events.

Alternative Fact: If you don’t use MVI your friends will make fun of you, you won’t get a date for the PoBa community center dance resulting in working as a shoe salesperson with Al Bundy :-) This is a direct quote from the Farmers Almanac which is never wrong.

MVI with SwiftUI / Combine Framework

Review of SwiftUI / Combine Framework:

Not having seen a single article saying that SwiftUI / Combine Framework can be built for MVI, let me say … SwiftUI /Combine Framework is great for MVI

Let’s map MVI to SwiftUI / Combine framework using the diagram from WWDC 2019.

Generated from SwiftUI slide @ WWDC 2019
  • Intent represents an intention or a desire to perform an action, either by the user or the app itself. Here oddly enough called Action. This action is used to transition to a new state.
  • Model represents a state. Here oddly enough called State. Models in MVI ensure a unidirectional data flow. A place where the business logic resides. For every intention, the model produces one or more new states for its subscribers.
  • View represents the UI View to the user. Here oddly enough is called the View. Views are a function of state, NOT a result of a sequence of events.

As Apple describes SwiftUI / Combine Frame can be MVI:

  1. Single Source of Truth
  2. Unidirectional Flow of Data with all actions starting with an intent from the user or system.
  3. Components have no observable side effects. Every time you run it with the same input values, you get the same output.
  4. The framework manages the synchronization of data and view for you using reactive programming (Combine Framework*).

MVI with Android Jetpack Compose / Kotlin Flow*

* Kotlin Flow will replace LiveData & SharedFlow replace RxJava in the long term. I really don’t have facts to back this but it seams to be a pattern. It’s just one less library to have to deal with. So we will assume the reactive library is Kotlin SharedFlow.

I will provide a future article covering Android MVI with this structure:

  1. ViewModel — Consume Actions, Process Model Changes, Emits a state.
  2. State — Kotlin Sealed Classes: Loading, Content, Error etc …
  3. Action — Kotlin SharedFlow: data emitted as part of the state from the ViewModel (https://github.com/Kotlin/kotlinx.coroutines/issues/2034)

We can build our Android MVI and make it similar to SwiftUI / Combine MVI.

Why is this important

If we frame our iOS / Android apps in the same way …

Language: Swift = Kotlin

Declarative UI: SwiftUI = Jetpack Compose

Reactive Framework: Combine Framework = Kotlin Flow

UPDATE: Reactive Framework: Swift AsyncPublisher = Kotlin Flow

Than building both with MVI can lead to better collaboration between the iOS & Android teams.

We are all moving toward this …

~Ash

--

--