06/02/2023 — My views have evolved and I no longer recommend MVVM pattern for building SwiftUI applications. You can read my new article “Building Large- Scale Apps with SwiftUI: A Guide to Modular Architecture”.
Apple announced SwiftUI at WWDC 2019. SwiftUI is a declarative framework for building applications for Apple devices. This means that instead of using Storyboards or programmatically generating your interface, you can use the simplicity of the SwiftUI framework.
SwiftUI does not follow MVC architecture. This means when you create a brand new application in Xcode 11 and enable SwiftUI, it does not create any controllers. This does not mean that you can’t use MVC design pattern with SwiftUI, it simply means maybe a different pattern (MVVM) can better suit your needs.
We will be consuming the latest headlines from NewsAPI.org website. It is recommended that you register with NewsAPI.org website to obtain an API Key, which will be mandatory for making any requests to the service.
Webservice and Models
Before jumping into SwiftUI, let’s go ahead and create our Webservice which will be responsible for retrieving the latest news from the NewsAPI. The Webservice is implemented below:
The loadTopHeadlines function retrieves all the articles and populate the Article model. The Article and NewsResponse model are implemented below:
The models will get the data from the webservice and then hand it over the View Models which will be responsible for displaying it on the screen. The ArticleViewModel represents a single article which will be displayed in a cell contained in the List control. The implementation of ArticleViewModel is shown below:
The ArticleViewModel conforms to the Identifiable protocol since it has to supply data to the List. The List uses the id property to make sure that the contents of the list are unique.
Next, we will implement ArticleListViewModel. This view model is responsible for reflecting the contents of the entire screen. ArticleListViewModel will also utilize the Webservice and retrieve all recent articles.
There are couple of interesting things going on in ArticleListViewModel. First, you will notice that it conforms to the BindableObject protocol. This means that it can publish events to the subscribers and can be binded to views on the screen. The only requirement of BindableObject is to implement the didChange event. The didChange event will notify the subscribers of the new data that is available.
In the fetchTopHeadlines function we make a Webservice request to retrieve all the news articles. Once, we receive all the articles we assign to the articles property which has a didSet. This fires the didChange passing in the self which in this case is ArticleListViewModel.
Now, the only thing left to do is to make sure that the articles are displayed on the screen. Let’s see how SwiftUI can make this super easy!
The declarative style provided by SwiftUI makes building the interface very easy. This is the complete code for SwiftUI (ContentView.swift).
The first thing to note over here is that the model is marked with @ObjectBinding. This means when the model is eventually set, after the asynchronous call, it will render the screen again by executing the body property. If you replace the @ObjectBinding with @State then will still work as expected. But the purpose of @State is different from @ObjectBinding, which will be explain the future. The screenshot below shows the app in action.
I really hope you liked the article. If you want to support my work then check out my latest course on SwiftUI below.