A New Approach to StateFul MVVM

Barış ŞARALDI
5 min readOct 19, 2022

--

Hi everyone. Before mentioning architecture, We need to know how I should choose architecture. Honestly, there’s no perfect universal app architecture. An architecture that works best for one project might not work best for your project. When establishing an architecture for you and your team to follow, there are many different aspects to consider. So the best architecture is the best adaptable architecture to your project. You can read this article for more information.

I changed my project a short time ago. I the new architecture used in this project that I have never seen before. It is called stateful MVVM. It keeps all MVVM features but reinforcement new features. Such as state and coordinator. It so a complicated approach for those who see the first time. So I applied a new approach to the state layer to both understand better and reduce the difficulties of architecture.

In this approach, instead of storing layers, I used combined power. Because we just need listenable classes. Using combine, we can listen to ViewModel into viewController. Let’s start! examine all things of the new approach.

I will examine architecture in four main titles. Firstly, our lead actor is Combine. The supporting actors are MVVM, the State, and the Coordinator.

Combine: Combine is Apple’s framework to work with asynchronous events in a unified and reactive way that ensures your app is always up to date based on the latest state of its data.

What are these asynchronous events, you might ask? Anything that happens over time in your application can be represented by what is known as a Combine Publisher — network requests, user input, notifications, KVO, and many more. And since Combine unifies all of these different mechanisms under a single interface, this opens the door to interesting and powerful ways of composing logic and work in a declarative and universal way.

The combine is also tightly integrated throughout Apple’s SDKs. For example, the UI framework SwiftUI uses Combine to ensure your app’s views stay up to date, which makes Combine a must-have for your skillset.

MVVM: MVVM stands for Model, View, View Model. It describes the flow of our data and the separation of our concerns. The following imagery can represent it.

MVVM Flow

Coordinator: The coordinator pattern provides an encapsulation of navigation logic.In other words: Instead of pushing and presenting your ViewControllers from other view controllers. All the screen navigation will be managed by the coordinator.

Coordinator Pattern Flow

State: Domain State Container in charge of coordinating other actors (like network services) to perform business logic and side effects. It usually sets a new state as the final result of those side effects.

Finally, I will mix that three structures. The main structure will be MVVM on the other hand coordinator and state structures will help to the main structure. The coordinator will present a new view, pass data between the new and old view, and dependency injection will be constructed here. The state will change the behavior of view, thanks to the results of the view model business logic.

StateFul MVVM Flow

I did a project to explain better. I will show all titles with code.

Coordinator: We will handle all navigation processes with the coordinator so that we need some properties and functions. We provide needed things with coordinator protocol.

Coordinator Protocol Codes

We will conform CoordinatorProtocol to base Coordinator class.

Base Coordinator Class

Now we have all properties and functions to apply Coordinator Pattern first part. Then we will call created Coordinator class in SceneDelegate to raise app navigation. To apply the Coordinator Pattern we need to add a builder. When we create a view controller, we will add a builder.

SceneDelegate

The app is now up. NavigationController is our parent viewController. Hereby we can use all power of navigation such as navigationBar. Let’s create our first ViewController and supporting classes. We start the first builder.

Builder Example

Dependency injections, viewController initialization and Storyboard instantiating should do in the builder. Because This is the rule of the coordinator pattern. We came to the hottest point of the article. We will explain what is the differences between the Stateful MVVM state layer and our state layer.

ViewModel Example

We created state property writing @Published wrapper. Thanks to @Published wrapper, state property being listenable. We can listen from viewController and we will see every change of states. How do we do this?

Listening States

State property is working like a publisher thanks to @Published wrapper. Publisher protocol is at the heart of Combine. This protocol defines the requirements for a type to be able to transmit a sequence of values over time to one or more subscribers. In other words, a publisher publishes or emits events that can include values of interest.

If you’ve developed on Apple platforms before, you can think of a publisher as kind of like NotificationCenter. NotificationCenter now has a method named publisher(for: object:) that provides a Publisher type that can publish broadcasted notifications.

To take data from the publisher we need to subscribe to it. We subscribe to the publisher using .sink after the publisher gives to us one completion and data. We don’t need all state store processes anymore in this article. Because combine does all the processes instead of it. Another question is how do we carry data from viewModel to ViewController?The answer is simple; we define the model property @Published wrapper also again. Our model property will become listenable. Now both state and model became listenable and we can see all changes.

Listenable Model Subscription

In addition to all of this, I used a combine network layer, image caching with combine, diffable dataSource and network error handling. You can see the entire project in the GitHub repo.

In this article, I have tried to explain it to you as best as I can. I hope it will be productive and entertaining content for you. Waiting for your feedback. Take care of yourself, stay with love…

Reference Links

1-) https://jobandtalent.engineering/ios-architecture-an-state-container-based-approach-4f1a9b00b82e

2-) https://www.raywenderlich.com/books/advanced-ios-app-architecture/v3.0/chapters/5-architecture-mvvm

3-) https://www.raywenderlich.com/books/design-patterns-by-tutorials/v3.0/chapters/23-coordinator-pattern

4-) https://www.raywenderlich.com/books/combine-asynchronous-programming-with-swift/v2.0

5-) https://developer.apple.com/documentation/uikit/uinavigationcontroller

6-) https://medium.com/swift2go/builder-pattern-in-swift-for-beginners-79415d30872e

7-) https://udaypatial.medium.com/writing-a-generic-reusable-networking-layer-using-combine-swift-ios-fe8e16404a13

8-) https://medium.com/@mshcheglov/reusable-image-cache-in-swift-9b90eb338e8d

--

--

Barış ŞARALDI

Remember dear hope is a good thing may be the best of thing. No good thing ever dies!