Build A Pokedex With SwiftUI 2.0 | MVVM | Network Layer | iOS 14 | Swift 5

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's going on youtube welcome back to the channel hope you guys are doing well and ready to code so really quickly let's talk about what we're going to be building in this video we're going to build this awesome uh swift ui pokedex here using the newest iteration of swift ui or swift ui 2.0 so there's some awesome new features that we're going to be going over how to implement using swift ui2 and we're going to be doing this in the mvvm architecture pattern so this is going to be a full-scale mvvm app with a networking layer models view models and all that awesome stuff all of this data is going to be populated from an api and we're going to be building it this out all in one video so without me wasting any more of your time let's go ahead and start building this so open up a new project in xcode select app hit next and you're going to want to make sure you have all three of these things selected before you create your project so swift ui for the interface lifecycle is swift ui app this is a new feature and then language is swift so i'm going to call this swift or sorry pokedex swift ui tutorial and i'm going to hit create and xcode is going to create this project for me so really quickly guys i do have some extra functionality in this that we're not going to be building so i do have this like cool feature button and or sorry filter button that allows you to filter all the pokemon then i also have you know the ability to click on a page here and go to like a pokemon detail view and have some of their stats displayed with like a cool graph if you guys want all this extra functionality the completed source code will be available on my website at stefancodes.com shop and you'll be able to purchase that and see the extra functionality in there for your application it includes some pretty cool uh stuff with swift ui like how to go from one screen to the next and how to you know build some graphs and build some more a little bit more complex ui here so once again that's available at stefancodes.com shop the link is in the description to this video but anyway uh let's go ahead and get started so something i always do when i start a project is organize my directory so let's go ahead and go here and you can right click on your the folder name of your project and say new group or a quicker approach is you just highlight it and hold down command option and end so we're going to create three folders one for our model one for our views and one for our view model okay so the first thing i want to do before we get started with this app is building out each one of our pokemon cells so here's sort of the structure of how we're going to do this we're going to build the ui for the cell and then we're going to populate our main view here with a bunch of those cells in this lazy in this uh sort of grid or collection view layout and then we are going to build our model or data model for our pokemon and then we're going to build our view model and we're going to add the networking layer as sort of the last step but uh first we're gonna build the skeleton of the ui and we're gonna start with the pokemon cell so go up to your view and we're gonna hit command n and create a swift ui view and you're gonna just go ahead here and say pokemon cell okay so what do we want this view to look like so we're gonna you know just do our best to make it look like this guy right here so uh first thing i'm gonna do is make this a z stack and let's go ahead and hit resume on our preview provider so that we can see what this looks like it should just be a blank white screen to start with uh and while that is going let me talk about why so we're gonna have this background layer as like the like sort of bottom layer of our uh cell really quickly guys select iphone pro max or you know if you want to keep it as the ipod 7 touch whatever the hell that is you can do that but i like looking at it in this layout um so the z stack is going to be like the bottom or the background layer of the cell so really quickly i'm going to just go ahead here and give this a background of color.green and you notice that nothing happens just yet um but you know once we start adding things to this cell um you're going to see that background color of green take effect so really quickly let's just go ahead and add some text right here and let's say bulbasaur and you can see that it has that green background color right so really quickly um you know from a layout perspective we're going to want uh inside of this z-stack we're going to want to put a v-stack in there because we have things stacked vertically on top of each other or you know in a vertical layout so i'm going to wrap this text in a v stack so you guys can go ahead and hit command and or hold down command and click on that and say embed in v stack now really quickly this option only shows up if you have the preview provider open if i were to say like go up here and say show editor only and you click on that guy that option is not available to you so keep the canvas open and it makes your swift ui development a little bit easier so now we're gonna also want two things down here right we're gonna want this little uh text guy and a picture so within this v stack we want an h stack because this is like the things that are stacked on top of each other but you know the second layer is horizontally stacked so i'm going to go here and i'm going to create an h stack and i'm going to say text as poison and then i'm also going to create an image um right now we don't have this image provided just yet um this is available in the description of this video i'm going to drag and drop it into my project it's just a little picture of bulbasaur that we're gonna use as an image for like testing purposes or building out our ui so uh just go here and my image is just called one because bulbasaur is the first pokemon at least in the og version and now if we hit try again and let it do its thing it really quickly cheers guys i like to drink and code that's good we notice that we get like a massive image of bulbasaur so let's go ahead and go over how to fix this so we're going to go ahead and here and say dot don't want that say dot resizable and then dot say say dot scaled to scaled to fit and then resume that and see if it changes anything and it got even bigger so you guys are like stefan what the hell are you doing i thought you were trying to help me not hurt me and just give it one second so we're going to say dot frame and then we're going to give it a width of 68 and a height of 68. and you notice it gets a lot smaller and that i am actually not trying to hurt you guys i am just teaching you how to code so um now that's like the basic layout of our cell right we obviously have to add some um some touches or some like touching up to it and let's go ahead and do that now so first thing is we want this cell to be rounded so we're going to go to our z stack so if you guys get lost in like the bracket inferno uh we know that we want to add this corner radius to the actual z stack or the like the um the cell itself and that's all sort of wrapped in a z stack so just click the opening bracket of your z stack and then you go beneath that and add all your modifiers so i'm going to say corner radius and it's going to be 12. and then if i hit resume every time i hit resume i'm going to take a drink we notice that the cell gets rounded right so that is looking decent so far but certainly not good so let's go ahead and change our text colors to white and then add the appropriate padding so here i'm going to say dot font and that's going to be dot headline and then i'm going to say that foreground color is not white so that looks pretty good but we do notice however that we want this v stack or this uh item this little text here to be aligned to the left right so this is part of this uh like parent v stack and if we want everything to be aligned to the left we can apply an alignment modifier to our v stack so we're going to say dot leading right there and we notice that it just gets shoved over to the left if i were to say dot trailing it would get shoved over to the right so another thing guys is v stacks only have three alignment options it's leading center trailing h stacks have top center bottom right so you can align a vertically stacked thing to the left center or trailing edge and you can align a horizontally stacked thing to the top center or bottom edge so that's uh pretty important to remember anyway um let's see now we need some padding on that guy so i'm going to go ahead here and say dot padding dot top and give it a pattern of 4 and then give it a padding of dot leading as well so that looks pretty good now i want us to modify this poison guy so here we're going to say dot font and we're going to say dot sub headline and then we're going to also say bold okay and then we say foreground foregroundcolor.white so that looks pretty good and now you guys might be wondering how we get this cool little capsule view here so we're going to apply what's called an overlay and now we have to place this overlay content in here so just hit enter and then hit enter again to sort of like open up these little bracket these little parenthesis and we're going to apply this rounded rectangle overlay it's going to have a corner radius of 20 and then we're going to give it a fill of color dot white dot opacity and say 0.25 let me do this a little bit more and let's like zoom in so you guys can see that it actually does have a little bit of filling now or this little rounded overlay um but we need to uh go ahead and apply one more modifier to get this to work so go outside of this overlay guy and we're going to apply a actual frame to this text so we're going to go ahead here and say dot frame width is going to be 100 and height is going to be 24. and resume means i got a drink okay so now that's not exactly what we want right but it does expand the frame of this guy to widen out the frame of our cell and then actually give it like the desired size that we want so something with swift you got swift ui if you guys don't already know is like views dimensions are sort of intrinsically figured out based on the things that they are populated with so uh if i you know comment out this line for the frame you notice that my cell gets smaller and it shrinks to the size to fit the um intrinsically figured out or discerned frame of that text right and like things like text they they have an intrinsic frame because swift ui can just sort of figure out the frame of it based on the text content right but here we're applying our own custom frame to it and then after we do that it expands the height and or sorry mainly the width of the cell because we give it this like extra bit of width so now what i want us to do is actually apply some padding to this text and when we apply that padding to the text it's going to have the effect of uh expanding this little overlay as long as we apply that padding before we apply the overlay so we'll go over what that means in just a second so go ahead and just say padding dot horizontal and say comma uh i believe it's 16 oops and then say padding dot vertical is eight so that looks uh pretty darn good right so let's talk about what exactly this did so it applied some padding to the actual um text right so it said hey here's this text and now this text has these padding parameters and then the overlay gets rendered around that padding so if we were to like put this i say let's say after the overlay i think it would have a different effect so yeah it wouldn't do anything right so the reason for that is because uh when we apply this padding and we do it before the overlay it's going to say okay you're applying this this padding to this actual text and then you are applying an overlay around that padding right so you have to apply the padding first and then apply the overlay so that it actually the padding is completed first and then the overlay goes around all of the padding and um really quickly guys there's just a couple more things we got to do so like i want to adjust the padding of our picture a little bit so we're going to go here and say dot padding and you're going to say you're going to open up a bracket do bottom and comma dot trailing and just do a padding of four so when you you can always do like an array of padding and you have leading bottom trailing and top available to you and then uh if you know that it's going to be the same for whatever you're applying in that set of like padding in that padding array you can just apply that single operator or modifier of four instead of saying padding bottom comma four and then on a new line saying padding trailing four so it just helps you shorten things up a little bit and you notice that it gives us some spacing right there and um i think i want us to actually make this a padding of eight yeah so that looks pretty good to me just double check everything with my code right okay um one more thing we also want to apply a little shadow um and we're so we're gonna go here and say shadow oops shadow and then you're going to say color and we're just going to say dot green radius is going to be 6 x and y 0 0. so that gives it sort of like more of a three-dimensional look and those are that's like a really small thing but it really sort of helps give your app like you know some layers to it so that things don't look so flat right so you guys can't you you may or may not be able to see it in the completed app but there is actually a shadow around each one of these cells and just like i said gives everything a little bit more separation it makes everything look a little bit more 3d um so it's a small thing but you know it uh it helps so now that we've done that um now what we want to do is populate our v stack or sorry our main view with um a bunch of these cells so let's go to our view folder hit command n swift ui view and we're going to say pokedex view so now let's go and figure out how we're going to use this new grid functionality that we get from swift ui so basically guys first thing we want to do is place this inside of a navigation view that's how we get this like navigation bar up at the top we get this navigation title and that sort of cool functionality there and you know that's not necessary for this iteration of the application but if you ever want to be able to go to like a different view by clicking on one of those cells or if you just want the title up at the top you're going to want to place it inside the navigation view so just go ahead here and say navigation view and then within that navigation view so this is the equivalent of like a ui navigation controller we're going to place a scroll view and within that scroll view we're going to place something called a lazy v grid okay so this is basically the equivalent of creating a collection view you place this lazy v grid inside of a scroll view and that will give you this scrollable grid effect here so what exactly is lazy v grid a lazy v grid means the items inside of the grid um are loaded in a lazy fashion right so what the does that mean it means that um things are only loaded at on an as needed basis so basically this pokedex has 150 or 151 cells whatever it is we're not loading all of those things at once right and this is especially helpful when your v grid is populated from an api call you don't want to load all of those things on screen at once i mean imagine if this were to scale and you had like a thousand or ten thousand or one million cells right you don't want all of those to load at once you only want them to load as they are about to come on screen so this is very similar to the functionality of collection views and table table views from ui kit where cells were cued and dequeued out of memory as they are about to come on screen so really quickly as a cell is about to come on screen or go off of screen rather let's start with that first it gets dequeued into a memory cache and the cell that's about to come on screen is only loaded as it's about to come onto the screen it's not loaded on the initial loading of the view and then as a cell that was previously on the screen is about to come back into view it is pulled from a memory cache and then reloaded into the view so it gives you a really smooth scrolling functionality and that's what this lazy v grid is going to be so if we open this up it's going to ask us for columns and content right so we need some grid items here so we're going to create that up at the top so i'm going to say private let grid items equals grid item and then just go ahead and say dot flexible and then grid item dot flexible oops don't say dot flexible you have to open it up and then say dot flexible grid item dot flexible so this is basically telling our v grid that we only want two items per row so here's one row we want two items in that row right so then for my columns guy i'm going to pass in those grid items and for my content i'm just going to go in here and i'm going to say 4 each [Applause] and then hit enter on that and then here we're going to say 0 dot dot less than 151 and then for content just go ahead and enter on that and delete all of that extra jargon you know just keep the underscore in and then you're just going to go ahead and pass in your pokemon cell hit resume oh got a drink and you guys should notice that we get this really awesome scrollable uh grid of our pokemon cells so uh we do notice however and if you guys hit play on the preview provider you can actually scroll through this stuff so that's pretty cool uh one second guys getting a nevermind all right so um we do notice that our spacing is a little bit off right so there's some more space with our items here so in our lazy v grid you can actually just go ahead and replace this content guy you don't need that you can just have that bracket but do close off your parentheses so you do have this guy here go ahead and say spacing is going to be 20. so we have column spacing go ahead and hit try again so it's uh okay i believe we have to delete that yeah okay so you're it should look like this guys you have columns and then spacing and that is closed off by one parentheses and then everything else is just wrapped in a bracket um so that looks pretty good actually go ahead and change this to 16. i think that looks a little bit better so that's essentially the ui skeleton for our pokedex app and that really wasn't that hard to build like the only complex part was actually building out the ui of the cell and then you can see that it's pretty darn easy to just wrap all this stuff up into a scroll view lazy v grid run it for each loop and then place the desired view that you want the grid to be populated with so now we need to add our navigation title so something that's a little annoying is that you would think that you would just place this on the navigation view guy so to say navigation title and let's say pokedex and if you were to you know like stop and run that nothing happens right so you actually need to place it inside of your navigation view so you would go one bracket up and then place that pokedex guy in there and then we should see pokedex showing up right there you can say pokedex pokemon doesn't really matter and then as i scroll we notice that we get that cool navigation bar functionality right so now that we've accomplished the skeleton of the ui i want us to go ahead and start introducing our model and networking layer so well let's uh start by creating our pokemon data model and then we're going to go over reaching out to our api and getting all this data and then we're going to use a view model to populate all of these pokemon cells so really quickly just go ahead and hit command n on the model file select swift file hit next and we're just going to call this pokemon so the concept behind this guys is that each cell is going to be populated with a pokemon and each one of these pokemon has you know some common properties they have a name they have a type and then they have an image and we're also going to associate a background color with each one of these pokemon so let's go ahead and start coding out what we want this class to look like so we're going to say struct pokemon and it's going to be it's going to conform to the decodable protocol as well as the identifiable protocol then we're going to say let id int let name string let's image url is a string and then we say that type is a string so this is all we need for the current setup of what we have um in the completed source code guys once again available at stefancodes.com shop we introduce a couple more properties like height attack defense weight total and this description that you see here as well but for this case we don't need any of that stuff this is all we need to display here so um now that we have our data model let's go ahead and start uh looking start trying to implement our data model into our ui before we get to the networking stuff so i'm going to um go to let's see pokemon cell oh my god that's annoying so xcode just crashed on me which is unfortunate so bear with me one second guys damn it pokedex swift ui tutorial xcode project so i don't know what it is with this version of xcode but that just randomly crashes sometimes and it's pretty annoying but i mean that's just xcode for you one of the few complaints that i have about it and it doesn't even want to open for me so just bear with me while i get this open back up guys so basically what we want to do now is apply the apply our model to um and link it up to our view layer right so we want to like populate each one of these views with this pokemon object and have all of that stuff be dynamically populated as uh for each one of these pokemon right so obviously the name is just going to be whatever each one of the pokemon's name is image url for the image and type is going to be string before we actually uh introduce the concept of an image url we're just going to you know keep the stock image of bulbasaur because this isn't going to be functional until we actually apply our network layer and get the image url for each one of these pokemon so um let me go ahead and create some mock pokemon so let's say let mock actually we'll do that in a second let's just go back to our cell so view pokemon cell and what we want to do is require that this pokemon cell be initialized with a pokemon so we're just going to go up to the top here and say let pokemon be equal to pokemon right and if we go ahead and hit command b we're going to get some errors so error it's not telling you exactly what yet but basically now we can't initialize this pokemon cell without passing in a pokemon to it but before we get to that we're going to go here and we're going to replace this text with pokemon dot name got capitalized so whatever pokemon we pass in to the cell guys it's going to populate this text right here with the pokemon's name and it's going to capitalize the first letter for us now here we want each pokemon's type so we're going to go ahead here and just say pokemon.type and then here we're going to keep this as just that for now and then um what i want us to do is you know now we're going to create sort of like some mock pokemon to actually see what this looks like before we apply our networking layer so go back to your model and let's just say let mock pokemon be an array of pokemon and do this like bracket opening like that and just say dot init and just do this and for the id say zero name you can say bulbasaur [Music] image url we're just gonna say one type is poison and then add a comma there and then we're just gonna copy and paste this a bunch of times right so each one of these guys has to have a unique identifier i think five's enough for now so this mock pokemon array is just gonna give us like some mock data so here i can say ivysaur keep the image url as one for now because like i said we don't actually have these images yet uh poison yeah that's fine then this guy venusaur poison this guy we can make charmander this guy we can make charmeleon in this guy we can make charizard type is going to be fire fire fire okay and then here just delete the comma on the last one and go ahead and uh go back to your pokemon cell and then for the pokemon preview we can now pass in one of these mock pokemon from that array so we're gonna say pokemon mock pokemon and you can go ahead and say like give me the the pokemon from index three go ahead and resume try again oops uh yeah so this also has a an error here so we can go ahead here and say pokemon mock pokemon and then just go ahead here and say like give it the second one and you guys should notice that some different data starts coming up uh based on what we put in this sort of mop pokemon array hey eleven pro max sorry guys bear with me it's not my fault it's xcodes all right um and while that loads all right so you guys can see here that like it now is saying venusaur if i were to you know do this with like uh four it will say charmeleon and the type changes here right so now we notice that some of our data is getting dynamically populated which is pretty cool um so now what we're going to do is actually introduce our networking layer and actually go ahead and fetch all of these pokemon from our api so really quickly guys i have all of this json just sort of racked together here and the url is in the description to this video where all of this json or this json endpoint is located if you guys want to see what this looks like in more of a pretty printed version just go ahead and copy and paste this link into your browser hit command a to select all this stuff and then i like using this json formatter um i'll apply i'll supply the link to this guy as well it's jsonformatter.curiousconcept.com if you paste all of your raw json in here and hit process it will actually like uh let me process this guy right so it'll actually process that data for you and give you some like object notation of um what your json data looks like in more of like a like a pretty printed version so we have like evolution chain height id image url name type weight all that stuff so this is all the json that is represented in this url endpoint here so now that we've done that let's go back here and go to our view model and we're going to hit command and introduce a new file called pokemon view model um so let's see let me open mine up okay so let's import swift ui up at the top say class pokemon viewmodel and make it an observable object and then we're going to say at published var pokemon equals an empty array of pokemon so if you guys haven't seen this stuff before i will explain it a little bit later on really quickly it's like a little bit difficult to wrap your head around but once you get the concept down it's not that hard to understand and it's going to be easier to understand once we complete the full life cycle of the project so really quickly guys as a like some sort of uh no no no don't make it global let's go ahead here and say let base url equal and i'm going to copy and paste this guy like i said this is available to you in the description to this video so just go ahead and wrap it in quotes okay so this is the url that all of our json data is located at so right here we're going to write a function to fetch our pokemon so i'm going to say guard let url equal url string and then pass in our base url else return then i'm going to say url session dot shared that data task with request oops data task this guy so select with requests completion handler and all that stuff um wait uh i think it's we can just pass in our url data response error in all right just go ahead and hit command b to make sure we have no errors here right so for those of you who don't know what's going on we are essentially just creating a url request to retrieve all of the data from this this endpoint right here so we want to get all of that data into our app and then we're going to map all of that incoming data into an array of pokemon using this pokemon model that we just created so this we essentially want to create this like mock pokemon array but we want it to be populated with you know data that we're actually getting from our api not data that we just create manually so in here we're going to say guard let data equal data else return and then we're going to say guard let pokemon equal try json decoder dot decode array of pokemon.cell oops welcome damn it it has to be capital p pokemon dot self from data and then we're going to say dispatch q dot main dot async self.pokemon equals pokemon and do not forget to say dot resume all right guys so in theory this should work but unfortunately the data is a little bit janky in our uh in our json so we have this annoying like null guy here so basically what i did was i created all this data in firebase and then this is like the rest api version of that data and i did that because you don't really want to have to you know i didn't want to have to integrate firebase into our project just to get all this data but for some reason they put null right there so we have to remove that null and comma just to get all of this uh json data so if you guys go back to the json formatter you can see this null guy right here and that's pretty annoying so basically we just have to write a little function to um remove that from the json data that we get back so i'm going to write this quick extension and it's going to be on data it's going to say funk parse data and we're going to just remove a string from the data block and it's going to return an optional data object so i'm going to say let data as string equal string data self encoding is utf-8 let parsed data string equal data as string dot replacing occurrences of our string with not with just a blank string then we're going to say guard let data equal parsed data string dot data using utf-8 else return nil then we're going to say return data so basically guys what we just did there was we are gonna look at you know the data that we get back which is gonna be this guy and it's gonna give us back all you know this stuff here and then we're just gonna we created this function to be able to remove a string from that data and we want to remove that null in the comma so we're going to call this function part called parse data and we're going to remove that string from it and then convert it back to a data object and return that that way we can decode our pokemon object from that data so here all you have to do is go and say data.parse data remove string and say null comma okay and that looks pretty good so let's go ahead and see how we're actually going to apply this now so we're going to go back to our view god dammit xcode crashed on me again what the dude pokedex swift ui tutorial.xcode project it's like so ridiculous that that happens i don't understand what the hell is happening there but anyway guys um so after we fetch that data then what we need to do is actually populate our screen our main screen here with all of that uh that array of pokemon that we get back so let's see still being an to me sorry for the inconvenience here guys or just blame apple not me all right so um now when we call this fetch pokemon function it's going to reach out to the api it's going to parse that data for us so it gives it back to us in the right format and then we're going to in this guard statement it's going to use all that data and it's going to use our json decoder and give us back an array of pokemon so that's the whole reason we conform to the decodable protocol here if you guys aren't familiar with this i can't explain everything in this video but essentially it just looks at the raw data that you get back and if these uh properties match up with what comes back from the data it automatically assigns the properties to that pokemon object so then we reload the data on the main thread and say self.pokemon equals pokemon and what is self.pokemon it's this published variable here so basically this published variable guys is going to be applied in our pokemon view so i'm going to go back to our sorry our pokedex view so here we're going to create our view model in our pokedex view so i'm going to say at observed object var view model equals pokemon view model [Applause] and just go ahead and build that to make sure everything is working and it says build succeeded which is awesome so basically guys we just need to modify this for loop here now so instead of just saying for each and just having some static you know set of indexes or indices we're going to say view model dot pokemon and then we're going to replace this underscore with a pokemon and then here instead of picking from our mock pokemon data we're just going to say pokemon and build that and everything should be fine and i just want to go ahead and make sure this works before we move forward so we're going to replace our content view as the root view with our pokedex view so just hop here and into the pokedex swift ui tutorial app file and just go ahead and replace that with you know your root view if you guys did all that in the content view it's fine i just wanted to show you how to do that right there and let's actually freaking run this thing i don't know if we've actually run this guy yet um let me do it on the 11 pro max because i already have that simulator open and let's see what happens and nothing is actually going to happen right now because that api call has not fired off so here we can just go ahead and say init and then call fetch pokemon so you know basically fetch pokemon has to get called in order for all this stuff to work so now that we've done that run it again and it should start looking a little bit better so this is really cool guys like we're noticing that all of these cells are now populating with some dynamic data you can see the types here are custom the names are custom but the background cell the background color and the pictures still need to be populated with the correct data so that's what we're going to do next and then i'm going to go over and explain the concept between uh behind this published bar and this observable object stuff so if we go back to our pokemon object we have this image url property right here guys but back in our pokemon cell we're just having each one of our images being populated with the asset that we have locally in our project what we want to do is actually be able to have our project process and download an image url so the concept of an image url is your image is located somewhere on the internet and it has a url location and uh basically we want to add some functionality to our app where we can take that url in and download the image to our application so in order to do that i'm going to have us go ahead and install a swift package so go to file hit swift packages and go to add package dependency and i'm going to go ahead and paste this guy in here and something called kingfisher and guys you can get the link to this this the guy the url i just pasted in there in the description to this video so essentially a swift package is the equivalent of a cocoapod it's like dropping a third-party api into our application and this is essentially what we're going to use to manage our image loading right and the reason it's better to use a third-party api for this is because it has a bunch of functionality that you're going to want when it comes to downloading images in your project like image caching and doing it in the most efficient way possible and instead of writing that image networking layer yourself you can just follow these couple easy steps to do it so go ahead and just select kingfisher swift ui after you paste that in there and it should download that swift package for you and um now we're going to use this pokemon image url and we're going to use this kingfisher guide to actually download the correct image for us so let's go back to our pokemon cell and up at the top go ahead and just say import kingfisher swift ui so you guys will notice that you can now import this module into your project because we just downloaded this swift package dependency so um now go ahead here and replace image with kf image and then you're going to just say url string pokemon dot image url just like that and you guys will notice that if you run your project again you'll notice all the correct pokemon images showing up in your project so you notice it takes a second to load and that's because it has to fetch all and download all of those images but um and you guys notice that if you scroll really fast like you can see the lazy v grid effect happening here where you notice those images haven't been loaded until these cells come into view on the screen right and you can see that because for a second they're all blank right and then the image shows up and that's because the api calls the api call isn't being made until it's necessary to make it aka when the cell comes on screen but if you scroll back up you'll notice that all the images remain there and that's because it has a caching function where if the image has already been downloaded it gets put into a memory cache so that it doesn't have to reach out to the api and re-download the image every time you bring the cell back into view so that's why it's helpful to just go ahead and use the third party api for this image functionality so the last remaining step is going to be um getting the correct background color for each one of our cells so i'm going to hop back into our pokemon view model in order for us to do this so let me open my code back up and essentially guys we're going to create like a background color property on this um pokemon view model guy so we're going to say var background color and it's going to be a color and we're just going to do a switch on uh hmm let me see pokemon.type no that's not gonna work okay um so actually what i think i'm gonna do is you can go ahead and cut this guys we're gonna create um another struct for this let me think about the best way to do this so basically we want to determine the background color based on the pokemon's type um we can just write a function so let's say funk background color for type type which is a string and it's going to return us with a color right so then let's just do a switch on type and we're going to say case fire return dot red case poison return dot green case water [Music] return dot teal or actually guys go ahead and make this ui color because it gives us a little bit more color options and then here say system red here's a system green and then for water we're going to say return dot system teal and you know i think you guys get the idea behind this i'm going to go ahead and just paste the rest of the stuff in here and you guys can just you know pause the video and type it out i don't want to spend too much time typing this stuff out this video is already getting pretty long and default just say return dot system indigo so let's just talk about this function really quickly before we implement it so basically we're going to call this function and it's going to ask us for a type so we pass in that type and we're doing a switch on it and we're saying hey whenever the type is fire give me back a red color when it's poison give me back green when it's water give me oh yes when it's water give me back blue uh or teal we can replace this let's say system blue and then replace this guy with like system teal i think that's better but anyway let's go ahead and see where we want to call this function so in our pokemon cell we this is where we set the background color right um actually guys so we don't have access to the pokemon view model here and instead of creating an instance or we could just say let view model pokemon view model and then we could go down here and say view model or we could say uh color view model dot background color for pokemon.type and let's go ahead and run this and see if it works really quickly and it's not going to i'm going to delete the preview on the cell because you know we need to pass in a view model now and here view model you can just go ahead and pass in our viewmodel guy let me just close out the editor so we have more room to see the code and let's see if this works and then i'm going to go back through and explain all of this stuff guys so you can see all of this working really nicely now we got this really cool visually appealing um sort of layout and uh there's one more thing we got to do go back to your pokemon cell and instead of just applying a static green color um let's go up to the top here or yeah we we want to put this inside of like a property so let me see if i can do that let color equal and just put color in there that work so let's see if we can put this up at the top yeah i cannot use instance member pokemon so we could just init do an init guy here say pokemon pokemon view model view model pokemon view model and then i can say let color like this we can call it background color to be more specific then i'll just go here and say self.pokemon equals pokemon self.viewmodel equals viewmodel and self.color or backgroundcolor equals and then i can copy and paste this guy in there and delete this guy here okay so now we can go ahead and place this background color here and we can also place it right there right because you guys will notice that each one of our cells has a shadow color of green but we want it to have a shadow color of whatever the background color of the cell is so we just created this uh sort of class level property here in this initializer so we can have access to that in multiple places so we don't have to copy and paste this ugly like big block of code or line of code in multiple places so now if we run our code guys the project should be complete so if you understand everything that's going on uh you don't need to stick around for the explanations because that's all the rest of this video is going to be um i hope you guys enjoyed it if you choose to leave now but if you want to stick around for some explanations um it's going to take about another you know three to four minutes or maybe less to to explain everything we just did so really quickly i told you guys i was going to explain the concept of this published variable in this observable object guys so this is a concept that is unique to swift ui and the concept of declarative or reactive programming right so basically we're declaring this pokemon view model to be an observable observable object and then over in our pokedex view we create this observed object and then create an instance of our viewmodel so we're saying that this viewmodel conforms to or inherits from the observable object superclass and then when we create it in the view it's an observed object so basically the like how this all comes together is that when you have a published variable like this on an observable object class whenever this guy gets changed whether things get added to it things get removed from it or it starts out as empty and then we populate it using an api call when you have a reference to that view model inside of your view and you're doing something with that published variable so you know when this app starts out pokemon is empty and then we have to reach out to our api get all that data that we need import it into our application parse all of the data and map it into our desired custom object of this pokemon guy so that takes a little bit of time even if it's just a second if it's half a second the bottom line is this array starts out as empty and then when it gets populated um back in our view it's going to say hey this is a published variable that is part of an ob of an observable object and this view model has been declared as an observed object meaning hey we're sort of listening for changes that happen with this view model so when that pokemon guide gets published or when it gets set right then this for each loop is going to get executed again and it's gonna say okay hey now this pokemon array has a bunch of things in it so now we're gonna do a for each loop on it and we're gonna look at each one of the pokemon inside of that for inside of that for each loop and now we're going to create a pokemon cell using each one of those pokemon so really quickly just to do a recap on everything i just said is basically this view model is something that we're listening to changes on right it's an observable object and then in the view class you say hey we are observing this guy so you have to declare it as something that is observable and then in the view you have to actually observe it right just because it's observable doesn't mean it's actually being listened to by anything just because someone's talking doesn't mean anyone's actually listening to them you need a talker and a listener right so this pokemon view model guy is essentially the talker right it's observable and then in the pokedex view it's observed so then you have your published variable of pokemon meaning that hey because it's part of an observable object whenever it gets published or whenever it gets set then we're going to reconfigure our view with this pokemon array so back here you know inside of our scroll view we have this lazy v grid and we have that for each loop on the viewmodel.pokemon guy so if i hold down option and click on it it's a pokemon you know get set guy right so that means that whenever it gets updated we're going to re-listen to all those changes do a for loop through each one of those pokemon items look at each pokemon and go into this block and then create our pokemon cell where we pass in the pokemon and that's how each one of these guys gets populated with our dynamic pokemon data and we passed in this view model because we need a reference to it to be able to get the background color right so we put this function for getting the background color on each one of our pokemon we switch through the type property which is right here and it's just a string um ideally you guys would want to make this an enumeration but you know i didn't really want to take the time to do that this is just sort of more of a quick fix for it and uh so yeah you do that and then each one of our pokemon cells gets populated with a pokemon and a viewmodel and it has to have a background color and in the initializer block we set the background color to be equal to the viewmodel background color guy and then here you know we dynamically populate all of our data and use this kingfisher image property to download our images from our api so that's going to wrap it up for this video guys like i said if you want the completed version of the app where you can actually apply some awesome filters here to you know add some cooler functionality to the app and uh you know bring it to life a little bit more where you can actually you know click on pokemon and get some details about them just like this that's going to be available on my website at stefancodes.com shop where you can purchase the completed source code for the whole project um so i hope you guys like this video you know if you do go ahead and subscribe to the channel there's gonna be a lot more stuff like this coming out also don't forget to check me out on instagram uh my personal instagram is linked in the description here it's just you know stefan.dallas and then my app stuff instagram is appstuffllc and like i said don't forget to subscribe to the channel guys appreciate your support also don't forget to check out my courses on udemy links to all that stuff is in the description as well so that's going to be it for this one guys we'll see you later peace out
Info
Channel: AppStuff
Views: 17,272
Rating: undefined out of 5
Keywords:
Id: f66ZCKEIZd4
Channel Id: undefined
Length: 63min 0sec (3780 seconds)
Published: Wed Nov 18 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.