I’m Only Happy When It’s MVVM — Part II
Last time, we built a bog standard “Hello, World!” MVVM based app in SwiftUI using Combine. In this post, we’re going to query an API for some items, and render them in a grid.
We will use our existing files, as well as make more. So, open up the project we built last time, and let’s get going!
(NB: This series will focus on using SwiftUI components to achieve everything where possible, and I will try to avoid wrapping UIView objects.)
To better separate our concerns, go ahead and make a new file for our
ViewModel protocol, and move its definition in there if you haven’t already done so. We skipped doing this in Part I for the sake of brevity. However as this post is expanding upon the foundation we established last time, we should introduce some better practices.
Next, make a new Swift file and call it
ServiceType. In here, we want a protocol which defines the bare minimum we’ll need to query most RESTful APIs, and an extension of the protocol to provide a default implementation of getting our data.
An example to copy pasta is attached below:
That’s right, we haven’t defined
RequestType yet. Let’s not forget to put each of these declarations in separate files to prioritise separation of concerns.
Lastly, before we define our service to query all emoji, we need to head over and look at the documentation. Why? We’re going to define a data model! This will be used by our service, and subsequently by our
ViewModel to render the view.
The documentation tells us that a returned emoji is comprised of six separate String types in a JSON object, and that the entire list is an Array. This is why our
EmojiListRequest defines its
Servicing The Engine
It’s time to build our service! Thanks to the protocol, it’s very straightforward. We need to define our
baseURLString , our array of
AnyCancellable , an initialiser which calls our binding function. If you hadn’t already cottoned on, it’s just like our
ViewModel from Part I.
Make sure to read all the comments to understand what’s going on in more detail. Since they’re included in the gists, details have been excluded from the article to keep things brief and exciting. 😉
If there’s a better way to handle something like this in SwiftUI/Combine-land, please drop me a line!
Updating The View Model
Go ahead and replace the
ViewModel from last time with the following copy pasta. We’re solely listening to our service, and taking the values into our view model.
Once you’ve done that, it’s time to update our view!
Go ahead and replace
ContentView with the following copy pasta.
We can see that because we are using a
LazyVGrid, we’ve needed to define an array of columns. It’s set to four, because the performance of the component with more columns was a little…meh. Maybe it’s the simulator, maybe it’s SwiftUI itself. Time will tell…
Read them carefully, and make sure the
Emoji type conforms to what it doesn’t yet. You’ll need a couple in there… a good
id ea is to the make the
id property the
codeString for better reuse.
If we go ahead and run the app now, we’ll see a navigation bar, and shortly after that, a list of emoji!
(NB: Some emoji don’t render, but that could be because the host Simulator is running iOS 14.1, not iOS 14.2)
With the completion of Part II, we’ve have taken a basic “Hello, World!” MVVM app, and turned it into a semi-functional real app. We copied and pasted aaaaaall the code, and that’s haaaaaaaaaaard work y’all!
If you enjoyed this post, please let me know what you think.
Catch you in Part III