Mohammad Azam
2 min readAug 8, 2023

--

Taking the example of client/server applications. What I usually do is instead of creating a VM for each screen, I create a Data Store/Aggregate model for an entire application. Keep in mind more Data Store/Aggregate models can be added but let’s keep the example simple.

So, if I am building a Movies app using MVVM with SwiftUI I may have MovieListViewModel, MovieDetailViewModel, AddMovieViewModel etc. All those VMs are talking to the same common source (server).

So, instead of creating 3-5 or 10 VM we can use a single Data Store/Aggregate model. This single data store can have methods to getMovies, getReviews etc. Depending on the size of the app, this single data store can handle the entire state of the application. Now, you can inject the data store into the EnvironmentObject and access it in all the required views.

The views themselves can also hold logic but NOT business logic. The views can hold presentation logic, transformation logic etc. NOT business logic. Business logic will be inside the data store/aggregate model etc or on the server. If I have any sorting logic then I can start putting that in the view. If I see that other views need that logic then I will move it to the datastore. This also allows us to break down views into smaller reusable views.

The actual call to the server will be performed from inside the datastore using some sort of HTTPClient. Here is the very basic implementation of the concept. When you look at this concept, it may look similar to MVVM but keep in mind that there are no VM and the StoreModel is the only datastore which controls the state for the entire application.

Gist:

https://gist.github.com/azamsharp/c3ade8b699d2a147ef7edc2f712d46cf

Give it a try and create a very simple app using this approach and see how it feels.

--

--

Mohammad Azam
Mohammad Azam

Written by Mohammad Azam

Lead instructor at a coding bootcamp. Top iOS mobile instructor on Udemy. Author of multiple books and international speaker. azamsharp.school

Responses (1)