Hi, Alex here from rebeloper.com. In today's video I really want to answer a question.
How to download images in SwiftUI with MVVM. Let's learn the MVVM pattern in
SwiftUI by building out this project. Hit that subscribe button open up Xcode
and let's dive in. So let's just jump right into the demo project and see what
we are going to build out today. Well first of all we have this empty list and
pulsating fetch button at the button. So let's push that button, there we go.
It's fetching our users and it is also populating the images from a URL, so hey
surprise we are going to learn how to also fetch URL images inside SwiftUI
in this tutorial. So that is what we can are going to build out today.
So let's just jump right into it. If you want to take a look at the code go ahead
and click the link down below in the description. So I have already created
this starter project and it is called SwiftUI MVVM entitled very cleverly and
what is basically MVVM? Well it is a kind of helper for MVC meaning that when you
code in MVC your view controller will get very ugly very soon with they
call it the massive view controller funnily and for that there is this MVVM
concept of separating your view code from your logic and it's called MVVM
because it's model view view model. Now the model is your model of your object,
the views are your views of course and the view model is basically the link
between those and it's called the view model. So let's see what we have here for now.
We have a ContentView with our dummy users we'll get back to
that in just a moment. In the view we have a VStack with a list of RawViews and
this is a custom view that I have created I'll just jump into it in just a
moment and we have a button, okay. Our list contains a dummy users and the user
in those dummy users is added to our RowView, okay. Here is our dummy users and
let's take a look at the MVVM user first. Okay! This is my model pretty simple.
It needs to be identifiable so we can add it to a list if you don't know what this
is go ahead and take a look at my previous video about a dynamic list.
So we have this ID as a UUID and we have some parameters our UI did and please
notice that we do have this ID this is used in our list but we also have
this UID because and this is an integer because in a database most objects well
I believe all of the objects will have a unique identifier and so this UID is in
fact the ID on the database and I have confirmed it to decodable because this
will be unwrapped from JSON file, okay. We have first name, last name, email and
avatar URL array we are going to fetch images in this tutorial too. So let's go
back here and yeah let's take a look at our review and our review is
basically having a user an MVVM user and a remote image URL. Now I won't go
into very much detail on how you have to or you can fetch images from a server
with the help of a URL of course but go ahead and take a look at the link in the
description and find out in the code and for that we have this remote image URL
dot Swift file that we are using and basically we are
creating an observable object for the remote URL and we are fetching basically
the image URLs data and storing it in this published
data variable. Once we do have or once this observable object let me just go
back here in the RowView we have created our observed object as a remote
image URL so once this observed object changes its value
all of this view is basically redrawn and it is checking if the image
URL data is empty. If it is then we are going to use our word empty placeholder
well this is basically an asset that I have added here. If not then we are just
going to use the remote image URLs data and we are going to cast that into a UI
image and because we are in SwiftUI that your image is cast into an image.
I know this is a whole mouthful but yeah that is in short how you can grab remote
images with a remote image URL and basically that's it we have talked about
our content view and our model. Now it's time for the good stuff. We are going to
create a user's view model but before we do that let me just go ahead and run
this app and see that these two dummy users are in fact going to be
populated inside our list. But of course we want to have something fetched from
the Internet and for that I am just going to go into the users view model
and before we just dive into how to create this users view model let's just
go and create our JSON files and some API and you can do this for free on
Makaroo if I have pronounced that correctly on
makaroo.com. So it command and click on this, sign up if you haven't already
done so. It's free. And it has a really good tear and
now we are going to build out a schema and for that an API. Please go ahead, stay
with me we are going to get to the MVVM part
real soon. So we are going to need this is a new
schema so we are going to do a UID and that is a row number that is an integer
we are going to let me just go back here to our MVVM user model. We are going to
use our first name. So let's paste that in there. A last name.
There we go, email is okay. I don't need gender and IP address at this moment.
We are going to add another field and that field will be an avatar, okay. And let's
just paste avatar URL there, okay. I am just going to fetch only ten rows
because that's okay. Make sure that format is set to Jason and select array
and include null values too and let's just preview this, okay. This is what we
are going to fetch when we do fetch this. But for that first of all let's save
this schema, okay and I'm just going to call this users, okay. Let's save it and
now we have to create or get API basically and let's create a new mock
API here and users JSON users generate ten, that is okay. So what we are
doing is using the user schema we are just basically creating, generating 10
users and we can access this in our browser with this. This URL, okay.
Let's see no API method was found oh maybe we need to save this.
Oh, let's create our API. Make sure that we hit that
and let's just try again, there we go. Here we have our JSON fight and I'm
just going to copy this API URL in back into my users view model under API URL.
We are just going to use that. So that's that makaroo real, real nice. Now let's
talk about what we came here for is the view model part of our MVVM part. So we
have created and I just go through line my line because it's kind of tedious to
try this out and we are really short on time. So we are just going to create a
simple observable object with a published variable of users array.
Now this users is of course the MVVM user model object and of course we have
an array because yet we are fetching more than one users and finally we have
this fetch users function that we are going to use on our button. Now if
you don't know what observable object published is go ahead and take
a look at another of my previous episodes on state and binding and
observable object and published on my youtube channel. So, yeah that is going to
cover everything about observable objects. Basically what you need to know
is when users is changed in any way we are going to get notified and we are
going to reload the list, okay. Now the list that I'm going to create in
just a second. Let's go over our fetch users, first of
all I want to remove everything from the users array so we get that nice
animation that everything is deleted and it is populated again. We guard let
unwrapped our URL because yeah this is just a string and maybe I just typed
in here rebeloper.com which isn't a JSON file, okay. Or maybe it's it
doesn't really exist. So if this exist then we can start our data task in
a URL session and of course make sure you resume that data task.
I always forget this make sure you resume it it will not start well
basically. I'm checking for errors and printing it out if there are any with
this session and I'm returning. If there are any errors I don't want to continue.
Again I guard let unwrap response as an HTTP URL response. If this
doesn't unwrap correctly then I return again. If the status code is 200, then
everything is okay, then I can move forward. Otherwise I'm just going to
print out the response code and maybe get some information about how to solve
this in debugging. Now I have to take care of the data. The data is also an
optional, so I guard let unwrap that and then I try to decode it with JSON
decoder, decode it's simple this is an API provided by Swift, okay. And then I
add that into our users and again please note that the users is a published
variable. So whenever it changes it will basically reload the list, okay.
We do try catch if there is an error we print out the error. So that is how you
fetch the data from and this API URL. Now yeah and basically that is it for our
view model. We have our published variable and we have a function that
fetches some users from a database. Now let's go back here on our content view
and wrap all of this up. As you can see here in the VStack first of all we have a
list let's comment that out and create a new list with having that view model in mind.
Now first of all if you want to use our
view model we have to create it. So let's see here I am going, under the at state
private for animation state let's just create an @ observed object, observed
object and this needs to be an observed object because the class that I'm going
to use is an observable object again. So var users view model equals users view
model, okay. So now we have our users view model and all of its properties. Now we
can go down and create our a list. So we are going to create a simple
list and I'm going to insert as the element the view models, there we go.
Users sorry user, users view model dot users as you can see we already have
auto-completion. And we are going to use user in and the
rest is kind of the same because we are just going to create a row view with a
height of 250, okay. And basically that is it. Now if we build and
run we won't see anything because at the moment the users list array, the users
array is empty. So what we need to do is just add some functionality to our
button and under the fetching it's pretty simple we are inside the closure
now so let's start with self and users view model and let's just call the fetch
users and yes this is everything you have to know and again please note let
me just delete this how simple it is and how structured it is. We are going to be
concerned in the view only about the views and we are going to be concerned
only about data manipulation fetching and so on inside the view model only.
So let's build and run and see this in action, there we go.
It's loading and of course because it's an empty array first we don't see
anything. So let's tap on fetch here and it is
going to fetch as you can see first of all we do get the placeholder image and
then we are downloading the images from the URLs that you can see here, so the
first one is Robo hash dot org and so on and we are getting a PNG back
basically. So let me just go back here and let's just scroll a little bit, okay.
And as you can see it's really smart. It doesn't really fetch the unshown
images on the, that are not shown on the screen just yet. Now there we go, that is
it for MVVM. Now you know how to use MVVM in SwiftUI. I want you to hit that
notification there because in my next video I'm going to actually talk about
SF Symbols in SwiftUI. If you're interested make sure you hit the
notification bell so you don't miss that video. In the meantime while you wait for
that one make sure you also check out these two videos that I have over here.
I talked a lot about iOS development, SwiftUI and how to code smarter. So make
sure to check out these videos as well and as always I will see you in the next one.