SwiftUI Masterclass: Build To Do List App

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this master class we're going to be learning to build a full-fledged to-do list app in Swift UI let's take a peek at what we're going to be building here's the app we're going to put together we're going to be able to sign users up and of course log them in with these beautiful screens here with some reusable components let's go ahead and sign in and peek further into the functionality of this app so here I've got a pre-existing account let me just sign in here and boom once we sign in we can actually see our existing to-do list items this looks great in both light mode and dark mode we'll see in a moment we can check items as done or mark them as incomplete we can also swipe to delete and of course create new items when creating a new item will also be handling errors so if we try to save without handling a valid title and inputting a due date we have this beautiful calendar for our due date here and once we create something new it automatically shows up in our list now we also have these two tabs at the bottom the first one is this list of course and the other one is the profile here where we have some basic info and a way to sign out this looks great in light mode and dark mode across the entire app hope you're excited destroy the like button below and let's Dive Right In welcome to lesson one of the Swift UI to-do list app in this part we're going to start setting up our project integrate Firebase and just create a bunch of empty files that we are going to work on in the upcoming Parts before jumping in hit that like button down below subscribe if you're into iOS open up xcode and let's create a new project here so hopefully you have xcode installed already if not you can get it from the App Store for free the Mac App Store I'm going to assume you have some basic working knowledge of the Swift language and let's dig in so we're going to select the app template under iOS and I'm going to call this a to-do list app maybe we'll get rid of the word app the important configuration here that you want to use is Swift UI for the interface and of course Swift for the language here go ahead and continue and save the project wherever you'd like I will toss it onto my desktop here and we should get something like this in our window so on the right hand side you might have a spinner it's trying to load the Swift UI preview on the left we got our template for our content View and what we want to start by doing is actually bringing in Firebase into our project and like I mentioned we're going to use Firebase for authentication as well as a database AKA firestore so what we'll want to do is hit file at the top left hit add packages and I've already actually used this before so if I just search fire you'll find Firebase iOS SDK if you're not familiar with Firebase what you can do is just go to Google and search Firebase iOS and there are some basic steps where you'll get a URL to paste into here to integrate this to your project so cool so since I have it here already let me select it I'll continue here it's going to take a few seconds to resolve it the first time you do it it's a little bit longer but just bear with it and you're going to see a list of the various packages and libraries that Firebase offers and we're going to want to select a few of them from the list so just bear with it here there it goes okay so here we have a nice long list of stuff that is available what we want to check is Firebase auth which allows us to create and sign users in and we're also going to want Firebase fire store and Firebase firestore Swift firestore is the document based database that Firebase offers so once you've got all of those checked just go ahead and continue hit command B to build your project and we should be in good shape so it's saying that it's already building so we'll hit cancel and let that actually run over there let me full screen my window here all right cool so it looks like it did indeed successfully build and on the left hand side you should see all these package dependencies pop up so cool so now we want to actually bring in a configuration file so you can you're going to head to firebase.com sign in to your Google account and we're going to create a brand new free project here so here we will give it a name of let's call it let's see we'll call it Swift UI to do list that'll be our project name hopefully it's Unique we'll pretend like we read all this we can actually just leave all the configuration the same we'll select a default Google analytics account and hit create and let it do its thing so while it's doing that let's come back to our xcode window and in our project Navigator by selecting the top item here we want to make a few changes we are going to uncheck landscape for both iPhone orientation and landscape and upside down for iPad orientation that is indeed important here the other thing we want to do is for our display name we're going to call this to-do list this is essentially the name of our application that shows up under our app icon and we want to make note of our bundle identifier here for me it's io.ios Academy dot to-do list we're going to want to enter this into Firebase in two seconds So speaking of which looks like this is done let's continue here and now that we've created a Firebase project we need to add an IOS app to it by selecting iOS and here is where you're going to want to enter that bundle identifier so we'll do iOS Academy dot to do list to make sure your casing does indeed match I believe that should be good Yep looks good to me and we'll put in a general name here so I'll call this let's call this iOS to do list all right we can leave that Apple ID empty and when you continue here what it'll spit out in the next step is this Google services plist file and you'll need to hit that button to download it and we're going to bring this into our project it's basically all the configuration files well it's one file with all the configure configuration information a bit of a tongue twister to make sure Firebase successfully connects to our client app or IOS app so we're going to skip all those Jazz since we'll do it ourselves and let's come back to xcode and drag in this new file that we just got from Firebase so let me drag this in we'll drop it right there and you want to make sure that the target membership and copy items if needed is indeed checked so now that we've got the file in we do need to do two more tiny things in the console here to get our app prepped in terms of Firebase setup the first thing you'll want to do is open a build and go to authentication and just toggle this on we're just going to say get started and we need to let Firebase know what type of authentication our app is going to support Firebase does give us you know functionality for sign in with a phone number Google Facebook Etc but what we're going to work with is email and password so we'll just select it flip on the switch to be on and hit save cool so now we've got authentication set up and the other thing we want to set up here is our firestore database which is under build similar here we are going to hit get started and it's going to ask some basic setup the first step we're going to say instead of a production database let's start this up in test mode which is perfectly fine for a use case we'll continue we are going to then specify our location of our firestore server basically wherever our data is going to originate from whatever the default is most likely is fine go ahead and continue and give it a few seconds to get its life together and it should be good to go so alrighty let's give our application a build and run in a simulator we're going to be working with the iPhone 14 pro throughout this series so I've got that selected already so we'll hit this big play button at the top left which should indeed uh build and pop up our simulator like so for us there and we should see our empty application open and I believe it's going to say hello world let's jump back to our contents View and see yeah we should see Hello World pop up in the center here Maybe not maybe it's just a little slow bear with it the first time you run your app it can be a little slow so cool there it is it does indeed pop up um if you want to switch between light mode and dark mode which we will do periodically throughout this video you can hit command shift a and that's how you can switch that you just saw me do it right there so now that we've got that good to go we do need to do one more thing to actually tell our app to connect to our backend AKA Firebase what we're going to do is go into the to-do list app Swift file and this is basically the entry point for our app what we want to do is import Firebase core is what I'm looking for and we are going to stub out the initializer and we'll say Firebase app dot configure now when you do this and build and run your app everything should be working as before you won't visually see anything different but if your app does indeed crash that means most likely you forgot to bring in this Google services file in other words what it's probably saying is and what it's actually trying to do is it's saying hey configure this app with all the information in here but if it can't find it it basically freaks out and crashes and says hey this is a problem you need to fix it so now that our basic project is set up we are successfully connected to our Firebase backend here let me just refresh the page and make sure firestore is good to go as well what I'll do for the remainder of this video is just create some folders on the left here and some empty files that we will be filling out throughout the next several videos so let's create some folders so you can hit this and hit new group right click and hit new group or you can hit command option n and I guess what we'll want is four different folders the first one will be our views the views folder will basically hold what it sounds like it's going to hold everything the user will visually see AKA views we are also going to have a folder called view models and these are going to be objects that allow our views to be intelligent and do stuff right so the actual logic of a view so for example when I hit you know log in after typing in an email and password an object and view models will actually handle that interaction for us next up we're going to want our models this is going to represent our core data types in our project so in our case we're going to have a user and a to-do list item right and number of users can sign up and a single user can create however many to-do list items that we'll be saving in our back end as well and what I like to do for the fourth folder is just create an other which is a grab bag of anything that that doesn't nicely fit into these three so let's start moving stuff around we'll put our Google services file in there we have our main app entry point we'll stick that in other as well we have our default content view I'll stick that into views I guess we can throw assets into other and we should be in pretty good shape all right so let that build let's give it a run once more make sure nothing accidentally broke with me dragging stuff around I can delete this Google services file from my desktop because it's been copied to the project and we're in a pretty good shape so before we wrap up here let's create some empty files and talk about some basic series workflow stuff so you're going to often see me refresh this preview on the right which is called the canvas and the shortcut on your keeper to do that is command option P you can also hit the little refresh button that you had seen there you can drag the section here for our canvas and our code respectively so I like keeping it as small as possible where I can see it and our code has enough room to breathe and I'll bump up that font size as well and let's create some Swift files and talk about what on Earth we're going to need so I believe this simulator has the finished app on it already so here we are let's take a look at it so this is our login screen so we definitely need a login View when we hit this button we get a register view which is awfully similar to login but we do need a view for that and if I go and log in here if you bear with me and I believe my super secret password is this password you'll see we'll probably want a view for our list of items Want A View to enter in and create new items and will want a view for the profile here as well so irrespective of how on Earth we're going to actually create these let's create Swift UI views that are going to represent all this jazz so here we have content view I don't like the name that much I'm going to change it to main View and this is basically what our application is going to open to just make sure that you rename it in both your implementation here Down Below in your preview as well as in your applications app file so in its window group the file the view that it opens up to is your main View and that's a much better name than just content view which is a little generic debatably main is generic as well but that's okay so let's create a new file in here by hitting command n and we will be searching for Swift UI views and let's start creating the views that we briefly discussed here so we have profile view so I'll call this profile view and we're not going to be doing anything in these views in this video we're literally just creating these empty views and files that we can work with later on so here we'll have to-do list items view so this is kind of what it sounds like this will serve this tab where it shows all of our items we'll want to view where we can actually create new items so let's create a file for that as well and this one will be new items or new item because we create one item at a time singular new item view alrighty looking pretty good and then we definitely also did have a login screen so we'll want a login View looking good let's create another Swift UI file for registration here we will have our register view all right and let's think about what else we might need so here we have on the list of items a list of these like draggable row things so one could probably infer that hey we could probably you know stick all this in the to-do list item view but maybe we want each of these rows we want to have a separate abstracted view a file where we can basically design the way that this row looks right having a little check mark on the left or on the right I should say having the labels on the left things of that nature so what I'll do is create a swift UI view for that as well so we'll create a swift UI View and we're going to call this a to do list item View and not to be confused with our previously to-do list items view so what I'll actually do is let's rename this to to do list view we'll get rid of the word items just so the naming is not as similar make sure you get rid of it in the implementation and then make sure you get rid of it down in your review as well hit command B to build make sure everything is still building if you have any errors to check for typos and things of that nature and those are essentially all the views that will most likely need I might have forgotten one or two but I digress we can add them along the way as we build now let's create some more files so in models I have briefly mentioned we have two models in our project so we'll create a swift file and we're going to have something that represents a user so whenever someone signs up and then of course we're going to have something that represents a to-do list item so this is the data itself that we are going to basically be working with you can imagine in larger apps you'll have tons and tons of models but in our case this is what we will be working with awesome so the last thing we're going to do is create a view model Swift files the way that I like to think about this is that every view most likely will have its own view model so the simplest way to approach this is for the uh seven views that we have down below let's just create seven Swift files and what I like to do is just take the name of the view and then append the word view model at the end of it so in this case we have main view view model and it's just a swift file for now we're not going to do any implementation so let's just get these created and out of the way that way we kind of have a picture of what our overall project is going to start looking like so let's do profile view stick on view model boom created let's do this a few more times for our other ones and then we can get on with actually the good stuff and creating stuff in the upcoming videos so here we have to-do list view view model I realized the word view here is redundant it's by design for consistency so just run with it similarly we have our new list item or rather our new item View I'm going to confuse list and item I feel like a lot throughout this video so bear with me it's a new item View stick on view model good to go next up we have our login and register views alrighty let me create that so here we'll have our login view view model alrighty let's create another one for our register view view model and I'm flying through these file Creations just because you know we all can learn from creating one how to create the others but the important thing is just make sure you have one file for review model per view and our last one here is our to-do list item view view model so to do list item view view model awesome hit command B which is going to build your project you can also hit the little play button at the top left and let's just hit that play button and we'll see our application running nothing has changed from the template we still see hello worlds but we're in really good shape to start building out each of these views the actual logic and interaction with it and making this thing actually work so thanks for sticking around hopefully you've gotten this far and you've got your project set up I will see you in lesson two let me know in the comments if you hit any issues if you have any questions destroy that like button for the YouTube algorithm as always appreciate y'all watching and onwards we go all right Party People welcome back to lesson two of the Swift UI to-do list app in the last video we did some basic project setup hooked up Firebase to this xcode project and created some empty Swift files and in this video we're gonna actually start building some stuff out so before we jump into things hit that like button below subscribe if you're into Swift UI and let's continue so we're gonna build out the login screen The View login view for our application and this is what we want to show when our user you know launches the app and they're not signed in so let's get to it so here we have our main view if you guys recall this is the view that we are opening up to when our app launches inside of our window group if you recall we changed it to main View and inside of here we have just an image and our Hello World um our hello world text so instead of this hello world text and image what I'd like to do is show our login view while we build it so we actually already created this login view Swift UI view on the left hand side here so we can just delete that and toss in login view like so we are also going to wrap this login view inside of a navigation view now this navigation view will allow us to show and dismiss a registration view if we need to right when the user Taps on register I'm also going to delete that padding there and we can jump into this login view you can hit the file on the left or you can command click on login View and hit jump to definition and this will basically just open up wherever that object lives which is in the login view Swift file so cool good deal now in our login view if we actually open up the simulator let's take a look at what we're aiming to build here I have the finished app on here as well our login view let me open this up and let me just sign out basically has this nice title at the top a subtitle this like wonky pink background thing and then we've got our form to sign in and then at the bottom we also have some text about if you're new here you can create an account so this is a view and the user interface that we're going to attempt to make starting off with our header so let me actually move this right next to xcode so we can have something to reference and we can start building it out so by just looking at this we can see that the elements are arranged vertically so my instinct is to start by using a vertical stack and let's put some comments in here at the top we're going to want a header we're going to want the login form itself with our Fields as well as our button and then we're going to want the create account Jazz you know below that so let's work on this header so for this header we want basically a z-stack because we have this pink thing and then on top of it we have two labels that are vertically oriented so a z-stack will enable us to do that so let's create a z stack here and this z-stack is going to start by having a rounded rectangle and maybe we'll make a corner radius of let's try a corner radius of just 10 maybe we actually don't need this because we actually are going to rotate this so let's actually just get rid of that make it zero now that we've got this here we want to set a color for it so we're going to say foreground color is going to be pink and if you see on the right hand side of our window we do have xcode automating basically the canvas update we can see our preview which is really nice so now that we've have got this um we want to adjust the heights we also want to rotate it and we want to move it up so let's let's do all of that so in our Z stack we've got this here let's adjust the height of this whole thing so I'm going to say frame is going to have a width and a height so we'll say our width here let's just do a hundred for a second and we'll say the height is 300. now the width should basically be wider than the entirety of the screen because once we rotate it we don't want it to be cut off so what we can actually do here is we can say hey use the current screens bounds dot with so basically our main screen this iPhone screen use its width and I'm going to multiply it by three so it is definitely wider than the available screen size here and you'll see momentarily why we're doing that so good deal so now that we have this here what I want to do is in the Z stack we're going to add a vertical stack here and we're going to have two elements right the first one is going to be a title so we'll say to do list and the next one is going to be a subtitle which I guess will say get things done obviously put here whatever you would like and we want to style both of these labels a little bit so let's make both the foreground color on these white this top one I will go and make bold and for the top one we're also going to set the font size we'll use a system size of perhaps 50 and then for the bottom one maybe we'll use 30. these are numbers that I'm literally just making up so if you want to use a different number by all means don't hesitate to so cool so we now have this header thing here it is a z-stack let me toss a spacer at the bottom of our entire v-stack to push this guy up let's make sure it does indeed move up all right it does move up cool now we want to rotate this pink background rounded rectangle and luckily there's an easy way to do this we can actually just apply a rotation effect which can take in a angle and we're going to say an angle gets created with degrees and maybe we'll do negative 15 I think that's the opposite direction of what we want let's try 15 actually but you can actually use any degree in here so cool we've now created this and to get the effect that I've got going on in this final product here where it's kind of from the top of the device we just want to move this pink thing up so we want the offset to be negative in the y direction so we'll say offset and what I'll use is y and let's try a negative 50 and see if that looks right probably need to smidge more so let's do maybe uh let's try like a negative like 100 and see what that looks like alrighty so that's a thousand that's a little too much obviously so negative 100 looks like it's okay but our text is now white on white since it's a little too low so we'll probably want to move that a smidge up um instead of actually moving the rounded rectangle up I kind of want to try moving this entire thing up okay so that looks a lot better but our text is now a little too close to the notch up here so what we're going to want to do is just move this down either we can use offset or we can use padding I'm going to choose to use padding for top and just make it 30. and if you look at that we actually have this header basically done so we have to do list we have a nice subtitle and it's looking pretty good so one thing that we are going to do often throughout this series is start abstracting stuff when it becomes a little involved so in this case our header is a little involved here so let me grab this whole thing and we're going to abstract it into a header view so we obviously don't have this header view thing here so let's create a new file it's going to be a swift UI file and that's not Swift UI let's make sure it is yep Swift UI View and go ahead and call this a header View and inside of this just paste on that z-stack and all that jazz we created in the previous file if you hit command B and command option P for Pinocchio basically just to make sure we don't confuse our letters there you should see that header view in here and back in our login view all this is a lot cleaner now so let's continue onwards let's make our form to create a form we can use surprise surprise a form a form is going to have a few text Fields one text field and one secure field the first argument will be the placeholder and the second argument will be a binding that we will create so I'm just going to create it in this for the time being so here we'll say at State VAR text is an empty string let me actually make two of these so we'll say email and password now we are going to move this stuff to the view model but just bear with me for the time being so here we're going to say dollar dollar email copy and paste this and this one will now become a secure field now for both of these we are going to set a field style so text field Style and what we're looking for if you just type in field style you'll see a lot of the available ones right down there in the drop down so we're going to look for the rounded variant and I'm just going to close that left panel so we have a little more room to work with already and if you hit command shift p you should actually see your Fields here they're a little difficult to see so let's actually see this in dark mode as well at the bottom of our canvas we can hit this little uh three iPhone uh three by two grid thing we can say show me different color variants and this will actually populate the light mode and dark mode variants here so you can actually click and see them both live as you develop so that's pretty cool let's create a continue button or a login button so we're going to create a button and the variant we want is with an action and a label for the action we're going to say attempt login obviously nothing going on in the action quite yet and in the label this is basically what we want our button to look like we are going to have a z-stack and this is going to be a rounded rectangle with a corner radius of 10. we'll give it a foreground color of blue and then on top of that I'm going to have a text label that says login we will make this bold indeed and if you hit command shift p to refresh your preview you should start to see your button but we don't actually see the text because we do need to say it is a foreground color of white by default it'll take a tint color which just so happens to be blue so cool so we've got our login screen coming along pretty nicely and finally to wrap this up what we'll want is that it'll create a count blurb at the bottom so for new users um like us actually we're going to create a way to navigate to the registration page so down here we'll create a vertical stack and in our vertical stack we're going to have a label that says new around here question mark and then we'll have a button that says create an account and here we will basically say show Regis duration so let's just make sure it does indeed pop up Okay it definitely does show up and let me go and just add a little bit of bottom padding here maybe we'll say 50 that way it'll just you know push it up a smidge and let's uh give this a run in our simulator and make sure it actually does look nice so cool this is our screen if we hit the home button we can actually compare it to our final product and they basically look like that and go barring some padding differences let's click on create account nothing happens let's actually hook this up to open the registration screen and then we will wrap this video up there after a brief overview and summary of what we did so we actually created this login view inside of a navigation view so if you open up the main View and pro tip you can hit command shift o to search for any file in your project you'll see we wrap this in a navigation view uh why did we do that we did that because we want to be able to navigate to another view in this case registration so let me actually move this navigation uh view whoops let's move that navigation view let's go back to xcode into login view itself so I'll come inside of here and with this v-stack I'm going to cut the whole thing and we're going to Nest it inside of a navigation View alrighty now that we've got this here we can actually say hey when we tap on a button to go to create an account we actually want to go to a particular destination so we can do this in a variety of ways but one of the simplest ways is by using a navigation link and we want the variant that has a title and a destination so we're actually going to delete this button and move that string here and this will more or less show a button but we're going to be able to say hey once we tap it go to the register View and let's just see the preview here and let's see what it looks like it should look basically exactly the same as our button from before it's actually indistinguishable the difference is when I tap on it we should be able to go to our our registration view our destination so let's give this a run in our simulator make sure it's all working and we'll be in good shape cool awesome so we definitely are able to navigate here we obviously don't have a nice UI here quite yet but we also have a back button up here I can tap into the field here and we do actually get our keyboard we might want to put this in the scroll view so our field is not overlapped by the keyboard one other thing that I will call out before wrapping up here is you can indeed change the way that your text fields in the form look I've used both the rounded Fields before you can also use the default style if you prefer the default style looks quite nice as well let's just give this a refresh in our preview here there are slight variants and you do want to make sure you don't forget to change this to password and The Binding here to Dollar password as well alrighty let's give this a builds and run let's make sure this is still looking good all right looks pretty good so I actually like the way this looks a little bit better because the entire form's background color is used for the fields as well which ends up looking a lot nicer maybe on this button down here we'll add a smidge of padding but I digress you can sit and optimize it and make it look exactly how you'd like your heart desires so this is our login View and none of it is functional yet as designed appreciate you all sticking around I will see you guys in the next lesson where we'll continue building out this app welcome to lesson three of the Swift UI to-do list app we're going to continue where we left off after we had built our login view so let's start working on our registration view before we jump in make sure you destroy that like button for the YouTube algorithm also say hello in the comments I always love hearing from you guys so we had created this pretty darn awesome looking login View and we want to create a registration view as well so let me actually get rid of our color scheme permutations here we don't really care to see them anymore we just want to see our single preview on the right hand side and I will jump into our register review as soon as it loads awesome so let's jump into register review and just to refresh y'all's memory are register view in our final product looks like this right so we can see we have a pretty similar looking header so we want to create that and then we also want a form similar to login we just don't want anything at the bottom so what I'm inclined to do is actually copy and paste a lot of our code for our register screen so let me actually do that let me create a v-stack maybe we'll start with this header View and let's see if we can repurpose any of this Jazz so I'll come into here and drop in this and let's refresh our preview on the right and cool we now have our header but clearly there's a problem right so in registrations case we wanted to say register and start organizing your to-do's but in this case we have whatever we hard coded to our header view so that's that's no good what we're going to learn in this video is how we can actually repurpose our extracted views to be generic right so we have one header view but right now it actually is a fixed angle in terms of its rotation it has some fixed strings for its actual title and subtitle um similarly it has a fixed background color so on and so forth so let's get to it so what I'll actually do here is we want to pass in to this header view a title and subtitle so here we'll have a title string and a subtitle string and instead of hard coding it inside our usage here this will take title and this will take subtitle now additionally what we'll want is we want a rotation angle that we're going to pass in and this is going to be of type double and finally we also want a background color which is going to be of type color respectively we want to make sure we use them here instead of using our hard-coded values so there will be background this one will be Angle now if you try to build you're going to see an issue right respectfully rather respectively to our usage we need to pass these arguments in we've said that this view takes in these four things but it's yelling at us starting down here and saying hey you didn't pass these in so let's let's pass them in so here this is the code for our preview so here we'll say title we'll just make it title subtitle will say subtitle for our angle maybe we'll make it 15 and for our background color we'll make it blue if you hit command shift p let's see if we're able to see our updated preview nope we are not able to see it because we still have an error elsewhere in our project so let's jump to our other two usages of our header view so there are two of them one is in login and one is in register so I'll start off with login so in login what we want to do is similarly provide all our arguments so the title will be to-do list our subtitle will be get things done our angle I believe was 15 and our background was pink let's copy this into our register usage of our header View and we're going to change everything so we'll say the title in this case will be register our subtitle here will be start organizing to do's our angle is going to be negative 15. let me fix that typo and let's make the background color orange and see what that looks like so now if you actually give your preview a refresh if it doesn't automatically you'll see our header now looks like what we want it to look like for register let me jump back to login and let our canvas load the preview here this still looks awesome in terms of what we want it to look like for our login screen if we go to our header View and refresh this you'll see in this case it's actually blue and it says title and subtitle and what it's getting that from is our preview of the Swift UI view right down here on line 40. so this is how we can reuse Swift UI views and components and make them configurable for different screens rather than copy and pasting everything we've already worked so hard to build and changing it for different cases right we don't want a login header View and a register header review and you can imagine as our app matures we might have you know a dozen head reviews it makes a lot more sense to just repurpose our existing code so that is a primer for reusing our stuff in different views let's jump back to our register View and inside of here we want to push this guy up so let me actually add a spacer here and that does indeed push it up and let's give this a run let's make sure that we are successfully able to go from login to register alrighty looking pretty good we might actually need to push this up a little bit more in this case because it does look like uh for this case we actually see a little bit of uh white or black at the top left so let me adjust this a smidge so let's jump into header review and we're going to change the offset so let me look for offset here we are offsetting this whole thing negative 100 we have a height figured out here let's make it negative 150 and let's make the height uh taller by 50. let's give that a run let's see what it looks like okay it looks good we probably need to move our text down another 50 so 30 plus 50 is 80. alrighty let's see what that looks like okay looking looking pretty good I would say let me click on this button to open up our register screen and I think these are looking a whole lot nicer you might want to move up your login form since it looks like it did get pushed down just a smidge so on our Forum in the login view we might want to say uh the offset in the y direction is negative 50 so that gets moved up as well so let's do that okay cool so this looks a whole lot better positioned and this looks good as well so that is all that we have got for lesson three make sure you hit that like button before clicking away and let me know what you think of this header did you use a different shape did you use a different rotation I quite like it I think it looks pretty nice even though it's a you know fairly simple but just having a nice rotation effect on it does give it a sense of uh creativity if I don't say so myself so appreciate y'all watching I'll see you in the next lesson welcome to lesson four of the Swift UI to-do list app we're going to continue where we left off abstracting the header View and working on the register view before digging in Destroy that like button down below for the YouTube algorithm and let's get to it so we learned that we can use injected Properties or rather configurable properties on our header view that way we don't need to copy and paste all the hard work that we did in our login view for this beautiful looking header now that we've got that set up we can jump back to register and we can indeed create a form for our actual registration so let's do that so I'm going to create a form here and inside of it we are going to use a text field for the user's full name first and foremost we're going to have a binding for it so I'm going to say this is dollar name we'll copy and paste this actually in just a moment let me say text field Style and what I'm going to use here is our default text field Style now that we've got this just copy and paste it a total of three times and change the last one to be a secure field and just change all of the bindings and placeholders so this one here will be email address this one here will be password and I actually never explained it or mentioned it but a secure field basically just uh shows you asterisks when you type rather than the text itself now it's yelling at me because this binding does not exist or this state so we're going to change these and create these right up above and we'll learn where we can abstract these two in a later video perhaps this video haven't decided yet actually so I'll make this one name email and password and these are actually the data properties to which Swift UI will write the value to as the user types so once I enter in my name it'll actually go to the name State Property up above so let's give this a build and let's do a command shift p just to refresh our preview on the right hand side we can actually also adjust this I'm going to hit this little icon and say show me this in the dark mode color scheme already we're going to offset this form by y negative 50 similar to what we did in our login screen and we also want a button here now similar to what we did for our header view it doesn't really make sense to start creating this button everywhere uh with you know the Z stack and this rounded rectangle so on and so forth so what we can actually do is create a custom button and our custom button can actually go and do all this stuff for us such that we don't need to duplicate all the effort so let me create a view to do exactly that so let's hit command n and we're going to look for a swift UI View and we're going to call this a TL button TL for to-do list it's a common naming convention where you you know prefix the name of your views with your apps abbreviated initials so you can choose used to call it whatever you'd like but inside of here I'm going to actually just paste in that button now this view similar to our header view we'll take in a title and it'll take in a background color so this title is what will show up on our button and this background title rather background color will be what our rounded rectangle does indeed show similar to our header we want to pass in some values for our dummy data for our preview down here maybe we'll say this button is Pink all right hit command shift p we should see our preview hopefully once xcode decides to get its life together awesome there it is and now that we've got this here we can actually start using it but there is a problem uh that problem is the fact that we need to be able to pass in Via a closure what functionality should be called when this button is tapped right like what action should occur let's change this to action here the way we can do that is with a simple closure so here I will say an action is a closure that takes no arguments returning void and inside of the button tab we can say hey just call that action closure that we've got up above here it's yelling at me that we don't actually have an action so we will fill that in and just like so we should be able to successfully build now let's jump back to our login View and this is where we're going to actually use that TL button so let's do it so let me make a TL button all right we're going to create it with a title we'll say the title is login the color is going to be blue and the action here will be attempt login now we could actually shorthand this and get rid of the word action put the parentheses there and get rid of this extra parentheses at the end so there is our reusable button and this is what we're going to actually be leveraging in our register view in literally two seconds alrighty just line broke it a little bit to make it a little neater now let me copy this and let's jump into our register view so at the bottom of this form we want a button with a background of green is what I'm looking for not register and we want our title of our button to say create account and here we're going to say attempt registration alrighty so that looks pretty darn good we want some padding on this button as well now instead of sticking the padding in every single call site of this button wouldn't it be great if a reusable component actually handled this for us so we'll dump back to our TL button and add the padding on it itself jumping back to registration and hopefully we should have a smidge of padding on our register create account button uh which it looks like we do let me just double check by adding a little bit of padding on this and see if that makes a difference it actually doesn't look like it does okay it looks like it did that time but let me let me actually remove it here because something looks a little a little fishy so let's actually get rid of the padding here and let's see what that looks like back in our register all right I think that actually looks a little better so instead of putting the padding on our TL button let's just use it in the call site so I take back the last minute of my rant in some cases abstraction is not good and there was a live example of me taking back and walking back a pattern so definitely these things are a little bespoke so if you feel something looks better in one way over another don't hesitate to change it so cool so we've got register looking pretty nifty let me give this a build and run in our simulator let's make sure that it does look nice so I'm a new user around here so I'll hit create account I should be able to type it here so I'll say I am John Smith my email is hello iOS Academy dot IO and my password is password so we can actually do a little bit of improvement on these fields we probably don't want to capitalize the first letter of our email so let's do all that so for our Fields let's add a couple of modifiers so we're going to say Auto capitalization and here we're going to say none we are also going to say auto correction disabled and let's do that for name as well so we'll say auto correction disabled and back in our login view similar for our email Fields here we are indeed going to say Auto capitalization will be none and that should hopefully make the usability and functionality a little better so it's not randomly capitalizing stuff so cool that is register and login now I have mentioned over the past two or three videos that we are going to eventually abstract this stuff into view models and we have these view model files here so let's actually do a brief example of this since it's going to start to be used quite often the upcoming videos so if you model essentially abstracts all of the business logicy data stuff that a screen or a view needs to function so on the login screen here we've got our email and password so instead of holding all the data in here which you can imagine can grow exponentially rather what we'll do is we'll create an object that holds it for us so let's jump into the login view view model and we're going to create a class in here with the same name as a file so login view view model we'll say this is an observable object something that we can observe we'll add init on here and we're going to copy and paste those two states on here and the difference is I'll change it to at published for both of them now back inside our login view we can delete these guys and we can say we actually only hold on to a state object called view model and it's going to be an instance of our new class called login view view model now you're going to get yelled at because this dollar email no longer exists here rather what we want is dollar view model so we'll say dollar viewmodel dot email similarly here we'll say dollar viewmodel dot password more or less we just moved this email and password into this single class and this is where we're going to have functionality for example we'll create a function in here called log in maybe we'll want a function in here to validate our actual email and password was indeed typed in and not just empty things of that nature right so instead of putting all this kind of functionality business logic if you will in the view we're going to put it on the viewmodel so the last thing I'll mention is I do have a habit of using a lot of keyboard shortcuts so if you ever see me closing this left panel it's command 0 and if you ever see me closing and opening the bottom console window this thing down here where we have print statements it's command shift Y and uh command shift o for going to different files across your projects I did want to call that out once more since I do do it a lot and it can get annoying if you don't know how I'm jumping around so much so that is all I've got for this lesson we covered a whole lot of stuff and I will see you guys in the next part welcome to the next lesson in the Swift UI to-do list app props if you've made it this far in this video we're gonna start working on validation for logging in so making sure the user did indeed enter a email password and then also writing the code to sign a user in once we start creating users so before we get into the things drop a like down below and let's dig in okay cool good deal so we created a register view we also have this login view model and we'll eventually want to create a register view model but for now in our login view model we want to actually call this login function that does absolutely nothing yet when we tap on this gigantic login button so let's actually do that so let's go to our login View and if you guys recall we have this TL button now we do also hold our view model in this view so we can actually simply do is just say view model go ahead and log in right so how do we actually log a user in well the first thing we'll want to do is make sure that hey has the user entered an email and password or are they empty right and if they're empty we probably want to show like an error message or something instead of the app just sitting there looking like it's broken so let's do that so the first thing we're going to say here is guard that email Isn't empty and that password isn't empty otherwise return meaning stop now what happens if as a user I just hit the space button a few times well that's no good so let me say email trimming characters in a white space isn't empty so if I just hit a bunch of tabs and spaces it's going to basically trim that out and make sure that it's not empty and we'll do the exact same thing for our password so let's say trimming characters in white space and I'll actually bump this onto the next line to make it look a little bit nicer so cool we briefly mentioned uh this published thing in the last video we I changed it from state but I didn't quite explain what it does so similar to State when it changes um a view will recompute and basically render any changes as a result of State changes and the published property wrapper is no exception so we're gonna actually see it in action now with error handling so let me give this a run and what I'm going to do is if we do have valid email and passwords uh filled in we'll say uh we'll print out called and a print will go into this bottom thing here which is our console so let's give this a build and run and you'll see if I type in test and I'll type in test into the password as well we'll see called gets print out at the way way very bottom right there let me actually clear that out and hit it again that way you guys can see it cool so called is there now what happens if I delete even one of these and I hit this login a few times Well nothing happens but as a user by looking at it shouldn't I get yelled at um for some reason basically some error message telling me hey what is going on why isn't it working and the answer is yes it should definitely notify you in some way shape or form that hey you need to fill in both email and password so what we'll do here is we're going to introduce a published property that is going to be error message it's going to be equal to an empty string by default and back in our login view what we will do is write in our form or you can do it above the form as well it's a little up to you it's subjective we're going to say if let message is our viewmodel DOT error message we want to show the error message which is our message we're going to say it's going to have a foreground color of red so we're basically going to show a red colored text label and that way we should be able to show the error so what it's actually yelling at me about here is that we're actually trying to unwrap this and that's actually not correct what we want to verify is that instead of it being non-nil we want to make sure it's not empty and if it's not empty we should show our viewmodel.error message and if you make that adjustment you'll see the error go away and your project should be building so now in our login function before we return we can actually say error message is please fill in all Fields okay give it a build and run and let's start by just hitting login and just like that we did see something popped up we actually can't see it quite yet because it's either underneath our login form or the color is not correct so let's see what's going on so I believe it's underneath the login form so what I'll actually do is I will wrap it inside of our form the reason it's underneath is because we're doing offset 50 so we're moving it up but let me hit this and just like that you'll see please fill in all Fields does indeed show up so cool so now that that is showing up let's write out the rest of our function here we are also going to do some very basic validation on the email address there are more quote-unquote uh correct ways to do this validation but we'll keep it simple we know that a email should have both a at sign and a dot in it so email at foo.com has both of those so we're going to guard that the email does contain a at sign and email does contain a period otherwise we're going to return and we're going to say error message equals please enter valid email and let's make sure we spell everything correctly and add nice periods at the end and whenever actually we tap that login button we want to reset the error message we don't want it to show up so we'll also just say when this function first gets called you know make it an empty string that way the error message will go away so once we have a valid email and we know we have got a password what we can do is we can actually start leveraging Firebase to log in so what I want you to do is import Firebase auth and Firebase auth will essentially give you functionality to try to log a user in with the provided email address and password the other thing that I will draw your attention to is we created this validate function I'm gonna actually make it private and we're going to move all of this Jazz into the validate function and we're going to have this function return either true or false if we're able to validate all of the users inputs and continue so if we don't have a valid email or password we'll return false same for email otherwise will return true now up here I can simply say validate and if we're not able to validate we're just going to stop now once we have validated we're going to say try to log the user in by doing the following so we're going to say auth dot auth which gives us a reference to Firebase authentication and we're going to say try to sign in with a email and a password so it's this variance down here email us email password is password and that's actually literally all you need to do to sign in so if you hit command B to build you'll see that your code is compiling and you should be able to run now of course you won't actually be able to sign in quite yet because we have not created any users and that's actually what we're going to work on in the next few videos but this is indeed all you need to do to sign in a user you might be wondering well how do I get rid of this login screen we probably don't want to show this and we're going to do that in a better way versus just you know manually dismissing this and showing something else so that is all I've got for this lesson kudos to you if you've made it this far we've actually done a lot more than what our app you know shows even though it's only two screens we've got a whole bunch of stuff set up and we're in really good shape so appreciate you watching drop a like before clicking on to the next lesson and I will see you there what is going on guys welcome to the next lesson in the Swift UI to-do list app in the last part we wrote the login functionality and in this lesson we're gonna finally start creating users registering them and actually logging into our app once those new accounts are created so drop a like down below and let's continue onward so we did talk about in our login view model how we can you know log a user in sign them in now we obviously can't do that yet because we don't even have a user so what we'll want to do is work on a register flow now we do have a registered view where we can input all this information but we don't have a registered view model yet so let's actually go and create one so let me just make sure I'm in the proper file I indeed am so we are going to want a register view model that is an observable object now if I jump to our register view you might recall we have three date properties on here for the name email and password we're going to take all of these guys and we will toss them let's see if I can find that view model again into the register view model and we will change them all to be published and that's a fancy little trick you saw me do there if you hold option you can actually get multiple cursors by just clicking and dragging and it's a good way to save a bunch of time when you're writing code so cool so now that we have got this we want to do two things when the user hits the register button we want to validate similar to what we did in login that the input is all valid and we also want to then create their account now creating their account also entails creating a new record in Firebase which I believe I have open here for that users we want to create their account and authentication and then we also want to insert the information about a user right so their name their email their ID right maybe not their password that's not very secure but certainly some information about them so let's let's do it so first we're going to say guard we want to validate so let's say validate here else we will return validate is going to return a bull similar to what login did and we'll want to to do three things or two things make sure the name email and password are not empty and make sure email looks good so let's do that so we're going to say guard that name trimming characters in white space character set is not empty and let me just copy and paste this a total of three times and just adjust it here otherwise we will go and return I do realize we don't have an error message here but we will just gloss over that and get this working first and foremost we are also going to guard that the email does contain a at sign and that the email does contain a period otherwise we'll return false and maybe one other thing that I want to enforce is that the length of a password is greater than or equal to six right privacy is important security is important so let's at least require hire our users to enter in something that is longer than six characters so password does indeed qualify which is what we're going to be using but a two letter password is probably not secure so once we have you know uh validated the user's inputs here we want to create a user so let's do that so we can do auth let's do that one more time after importing Firebase off which I forgot to do so let's import Firebase auth up here and we're going to say auth dot auth and we want to create a user with a email and a password email is email password is password and we should also get a completion block from this which will give us our newly created user rather our newly created user results and the error what I'm going to do after that is I want to make sure that we have a new user so we can say our user is our results.user and this user does have something called a uid off of it which is the newly created users unique identifier so let me actually call this user ID now once the user ID is received from this new user creation we want to actually create our own model for a user basically a data object that represents a user and insert it into the database so let's say private Funk insert user record now this function is going to take in a user ID and we are only going to in this function call that function so we'll say insert user ID user ID we do want to say self optional with that question mark and stick a week South up here since we don't want to cause a memory leak if you're not familiar with that I've got a dedicated video on it it's a detail that is important but I'm going to gloss over at this time just to make our app work before getting into the nitty gritty so inserting a user record in the database is actually quite easy now we first need to create a object that represents a user so let's jump into our models folder and we have a user file in here and let's create a user struct is going to be codable and we'll discuss momentarily why we need this and what it's going to be used for so our user is going to have a ID which is going to be of type string they're going to have a name they'll have a email address and maybe they'll also have a joined which will be a time interval representing when they did in fact join our app when did they sign up so this is what a user is going to look like so let's jump back to our register review model and say new user is going to be a user and we are going to create it with the id id name is name email as email and joined is going to be the current dates and we're going to say time interval since 1970. and now you might be wondering what on Earth is this the short and sweet of it is it's not able to we're not able to save a date object directly into Firebase into a database so there are a variety of ways you can do this you can save a string you can save the number of seconds from the date since 1970 we're going to go with that latter approach of doing this so now that we've created this new user object we need to insert it into our database so let's do that so we're going to say our database is firestore.firestore and to access firestore which is our database we do need to import firestore up here and now we can say firestore.firestore now the way that this database works is that records are stored in collections and documents so we're going to have a collection for users where all of our user in inserted records go so we'll say our collection of users we're going to want to have a document with the ID for our user ID which is being passed in right here and we're going to say set some data for this now if you look at set data it actually takes a dictionary in so what you could do and you could be tempted to do this is say hey well name is name and we can read all of this information off of this model up here but not only is that a little verbose but it's a little error prone as well what happens if you make a typo then suddenly you have a typo that doesn't match your model and it gets a little Annoying to be frank so the reason we actually made this user object codable is we're going to employ a handy little trick via an extension to be able to convert anything that's codable into a nice dictionary for us with strings and values that we can put into the database so to do that we're going to open up this other folder and we'll create a swift file called extensions and what I'll extend here is I'm going to write an extension on to encode a bull which is the part of the codable protocol that is responsible for encoding it to data and what I'll do is I will write a function called as dictionary that will return to us a dictionary of string and any and inside of here we'll do the following we first are going to say give me data from the current thing that is codable so we'll say data equals Json encoder and I want to encode self and the reason that we have this as a guard here is that we're going to say try optional and if we fail we're simply going to return a empty dictionary now once we have actually got data what we'll say is convert this to Json AKA a dictionary by saying Json serialization give me a Json object with this data and we're going to put a try which is why we're inside of a do catch here if we catch an error if we throw an error that we catch will return an empty dictionary otherwise we're going to cast this to string any and finally we can return Json otherwise a empty dictionary so if this is a little confusing not to worry this is kind of a bit of a workaround instead of doing things manually but it is something that will come in super handy if you're not super familiar with codeable and encodable I encourage you to read up on it it's not that difficult it's not as scary as it sounds but it will do wonders for you so let's jump back to our register view model if I'm not mistaken where we were before let me see where it went there it is and what we'll do here is we're going to say save or set data new user as dictionary this is what we expect to put into our database let's do a command B to build and let's see if we have any errors so it looks like it can't find dollar name email or password in our register view anymore which makes sense because we move them to the view model so let's stick a state object in here and we're going to save the view model for this view is going to be a register view view model you can create it just like that and this is going to now be dollarviewmodel.name dollarviewmodel.email and dollar view model say it with me dot password go ahead and hit command B to build and everything should be compiling and in fact we should now be able to create a user all right so let's uh let's give it a shot and now before we do so one thing that I do want to point out is in our main view for our app that it opens up to we're showing this login view directly right what we probably want to do is check if the user is signed in and based on that we want to actually show something else so how do we go about doing that well we're going to have a state object in here and the reason I'm doing this before we attempt to create a user is so we can actually see the app signing in uh in kind of real time so we're going to create a main view view model like so whoops let's try that one more time main View view model now we have a file with this name with I believe nothing in it so let's create a view model for this observable object and we're gonna have two things inside of here the first one is going to be published we're going to say current user ID and we are also going to have an initializer that basically takes nothing and we will also have a public VAR saying is signed in and the signed in is going to return the current user not being nil so bear with me we're almost done I promise we're going to import Firebase off and if we have a user that means we are signed in right so we're going to say auth dot auth auth.auth dot current user if this doesn't equal nil meaning there's a value for the current user that means we're signed in if it does equal nil that means we're not signed in and you might be wondering well why do we have this current user ID thing here and it's being defaulted to an empty string the reason is because we want to actually observe from Firebase when the current user changes and we can do that via the following we're going to say auth.auth and we want to add a did change listener so State change listener and what we actually get in this is auth which we can I guess ignore and a user and the user is important piece here because we are going to say self the current user ID will be whoops let's try that again will be user dot uid their unique ID otherwise is an empty string in other words whenever the user signs in or signs out this published will be triggered right and that will hereby update our view now we also are going to hang on to this Handler so the type of this Handler I don't actually recall but let's see what we can remember I believe it is a auth state change handle listener handle so here we can say self.handler and we also want this to be self optional to not cause a memory leak so here we will say weak self alrighty let's see what the issue is that it's yelling at me here about and then we can continue and we'll actually want to make this Handler a private variable so something that's mutable and by default it'll be nil so we're going to make it optional as well and I think that's actually why it's yelling at me here and that error indeed should go away we also stuck the week self here to not once again cause a retained cycle leaking memory the last thing I'll do inside of here is say dispatch queue dot main.async because assigning to this published property updates The View we do want to do it on the main thread I.E the main Q so now that we've got this view model here we can actually use it in our main view Swift UI View so we already had created this here let's make sure this is indeed created all right hit command B everything should hopefully be building and instead of just showing the login view every single time we can now use our newly created published property so we can say first and foremost if viewmodel is signed in and our view model the current user property is not empty meaning it must be assigned to something then we want to show the signed in States if signed in otherwise we're going to show the login view so the signed in state is actually going to be a tab view but just for now let's show the to-do list view just like that and in this to-do list view I'm simply going to stick in a label that says welcome to your account with an exclamation mark because we're super excited about it so I believe that is everything that we need to do let's create an account and let's see if this works if we have any issues we will debug them together so we're going to go to create a new account and I'm going to try to create a new account here so we're going to try to create an account so I'll type in my name we're going to type in hello at iOS Academy dot IO and our super secret password is going to be password and let me make sure I spelled that correct so if we don't get locked out of our own account let me just expand the console here as well and clear it and we'll hit this create account button and make sure something does indeed happen so I clicked it and nothing is happening and I bet I know why because we never hooked up this register button tab to actually call viewmodel Dot register so make sure you don't forget to do that back in your register view you want to actually hook up the action for your TL button so let's try that for the second time and let's see if we missed anything else so type in my name I will type in a email and I will also type in a pass password and hit create account and boom just like that we are in our account and the coolest thing about this is because Firebase can persist account State AKA auth if I rerun the app we should actually go directly to our account and that's because in our main view we're saying hey if we are signed in from our view model and we have a user ID Go and show the to-do list view the last thing I'll do is validate that we did indeed create database records and a new user so an authentication we do have this new user it actually even gives you the date when the last sign in occurred and in our database let's make sure we've got users there's our unique ID and boom there's all of our information so we've got my name we've got our joined time interval here which should just be a long number we've got our user ID and we've got our email so congrats we're finally signing people up we have an authentication system that works obviously no way to sign up quite yet we're going to work on that but kudos to you if you made it this far destroy that like button before clicking away let me know in the comments if you have any issues if you have any suggestions any problems you face I'm gonna do my best to help you all out thanks again for watching I'll see you in the next part welcome to lesson seven of the Swift UI to-do list app we're gonna pick up where we left off before we get into things and destroy that like button down below for the algorithm hit subscribe if you're still not subscribed into iOS and watching along let's continue so in this part we're gonna actually build out this connect account UI so we got a user created we are signed in but whenever we open the app we actually get just this like random screen where we just have a label what we actually want to see is a tab bar at the bottom and a nice uh you know profile title for the profile Tab and to-do list uh title for the other tab as well as a plus button at the top where we're eventually going to show a new screen to add new to-do list items so let's get to it so in our main view we currently are just showing this to-do list View and instead of showing this what I actually would want to show is a tab view let me just lower case that I and and a tab view allows as the name kind of implies to show a tab bar for each of the views inside of it so here we're going to have a to-do list View and it's going to have a modifier called a tab item and the tab item is simply going to have two things inside of it it's going to have both a label and a icon so let me create this label here and what I'm looking for is this one so the first one will be home and the system image that we're going to use is house now SF symbols is Apple's image icon Library so we're going to use those you can of course use your own image as well but we're going to use the ones provided by Apple since they are sufficient for our use case now the other tab is going to be for our profile view with the title being profile and the image being person dot Circle alrighty so hit command B and on the right hand side we actually see a preview for the login screen which is not ideal but we'll just build and run this into a simulator and we should hopefully start to see a tab bar at the bottom uh if we don't see it for whatever reason we probably screwed something up but we actually do see it so I see home here and profile and actually looks like the profile view that we created the template gave us this hello world so it is indeed changing so cool good deal let's jump into our to-do list View and let's start putting some stuff in here so we want to have a navigation view in here so we can actually start to see a title so we'll throw through a v-stack and we want to see a title at the top left here that says uh to-do list or some title more or less and the way we get that to show up is by adding a navigation title modifier there just gotta spell it correctly unlike me to this v stack in here so I'm going to do to-do list in my case and actually we'll copy this exact same thing into the profile view everything in here right now is just a template and the differences we'll just change the title that we see here to profile so give that a build and run and you should see a nice title at the top for to-do list and we should see the same thing we switched to the profile Tab and I'm just changing the light mode in dark mode here so you all can see what the two variants look like so the next thing that we want to do for our to-do list view here that particular tab is show a plus button at the top right and essentially once the user clicks on that plus button we want to show another screen and that other screen is going to be where the user can enter a title and select the due date for a new to-do list item now to do that actual everything I described basically showed it to the button at the top right we're going to use something called a toolbar and a toolbar let's see if I can find it this one here we want to just create a button inside of this now the button is going to take a action and label so the action don't worry about this quite yet but for the label we'll use an image with a system name and this is going to be I believe plus is the icon I am going for which will show a little plus icon at the top right that actually did indeed just show up there so we're in pretty good shape this is kind of the template for our logged in state before we wrap up this video I will do two important things uh the first one is we have a file for to-do list View and a to-do list view view model and we don't have anything in here so I will at least stub this out so we have something to work with so it's an observable object we'll put an initializer on here and let's actually just copy this and let's create one for profile as well so let's see here we have profile I will toss this in here it is going to be our profile view of your model and while we're doing this we might as well see any other files that are empty and take care of those so here we have our new item view view model so let's just add this in here as well it's a new item view view model and I believe that is this is the last one actually here this one is to-do list item view view model it actually looks like we have a duplicate here let's see what the difference is so this one is to-do list item View and this is a to-do list view item view model so let's just add a comment to there since their name so similarly so we don't screw them up so this is going to be view model for uh list of items View we'll say primary Tab and let me copy this into this guy here and let's just make sure we change the name here so this file is called to-do list item view so we're going to call this to-do list item to-do list item view view model and this is view model for a single to-do list single to-do list item view each row in items list so I'm just adding comments here for myself and mainly because their name so similarly that we don't want to screw them up now that we've got this created here let's just hang on to them onto on our actual Swift UI views since we are going to use them and then we can wrap up this video so for our to-do list view we can simply create here a state object and this state object will be of type our to-do list view view model which we basically just went and created so we should have that here and we're also going to want to pass something into this to-do list view but let's let's uh sidebar that for a quick moment and let's also jump to our profile view let's see if I can find it and in our profile view we will also create the associated view model pretty simple profile view view model make sure you hit command B make sure everything is still building hopefully no problems we didn't do anything too crazy and uh yeah let's uh do one last thing and then I promise we'll wrap up in this video and that last thing that we're gonna do is I mentioned we want to pass something into this to-do list view if you recall it's a two the to-do list view is what we use for our primary tab in our main view when we are in the signed in state what we actually want to pass in to this view is the user ID and the reason we're going to want to do this is because the user ID is what we will use to listen in real time for to-do list items for a particular user so we can basically just pass in viewmodel.currentuser ID the reason it's yelling at me is because in here we do need to just make sure we appropriately hang on to this so here we will say self.user ID is user ID and up here I will just create private let user ID of type string all right so we're in pretty good shape we want to also pass in a user ID here for our preview content and let's see if there's anything else we can clean up we can abstract this tab view if we want we can create a function down here we can annotate it at the view Builder and say this is a account View and our account view here is basically going to return some View and we can instead of making it a function make it a computed property just toss that in here and here we can say show the account view just like that if you build everything should be working perfectly fine this is abstracts basically what we had in the body here to its own computed property we did Mark it as a view Builder as well which allows us to basically do this let's give this a build and run make sure everything is still A-Okay and then we will wrap this video up and continue in lesson eight alright so we're looking at pretty darn Nifty everything is good plus button not working just quite yet but we do have two tabs where we have some real estate on our screen now to build I will see you in the next lesson where we'll continue building this hit that like button before clicking on over to the next part and I'll catch you guys there all right fine people of YouTube Welcome to lesson 8 of the Swift UI to-do list app in the last part we started setting up our basic account UI with these nice tabs and bars at the top the plus button here as well in this video we'll continue particularly working on presenting something when we tap on this plus button to create a new to-do list item so without further Ado destroy that like button down below and let's continue building so what do we have here well we have our plus button in place and that resides in our to-do list view particularly this button that we added to the toolbar and when we tap on it we want something to happen and that begs the question well what do we want it to do when we tap on it well similar to what we have done in other cases we're going to basically assign a binding that is going to inform our view that hey we want to show another view now the other view we want to show is our new item view so let's see if we have that here we do indeed have it here and inside of here what I will do is I'm going to start by tossing in a v-stack let's say command shift p so we can actually see this thing on the right hand side that's how we build this stuff by actually seeing it and let's start by creating a label here and we're going to say new item we're going to make this bold and perhaps we're going to bump up its font size as well I'm going to say this is a font size of size maybe like 32. once we've added that there the next thing we're going to want in here is a form and if you just think about the basic semantics of adding a new element to a to-do list app we want to have a title or a name call it what you will we are going to want to have a way to select due date and then basically a button so let's create all of these we'll have a text field is what I'm looking for here so we're going to say this is going to be either name or title call it what you will we're going to want a binding and like we've done in all of our other forms we're going to have a publish property in our view model I will call it title so let's actually stick that view model on here which we have not done yet so let's say State object VAR view model is going to be basically the associated view model that we have named super conveniently like so similar to other view models let's jump into here and actually start sticking on some published properties so I'm going to say published VAR title will be an empty string we also in this case want a due date and a due date by default will be a instance of a date and whenever you create a date it gets initialized as the current date and time kind of important we'll see in a moment why that is but let's actually create this we also want a date picker and with our date picker what we want to do is have a title key here for due date our selection is going to be viewmodel dot due date let's say command shift p let's see what that's looking like all right so we've got our due date here we also got a field at the top and we do want to have a date picker style and if you just type in day to Picker style you'll see that there's a wheel there's a default compact I'm going to change this to be let's try graphical I actually don't recall what that looks like but we'll change it and hope it's the correct one it is indeed the correct one it's the one where you can see the entirety of the um the the date as well as the time at the bottom which is what I'm looking for let's also go and add a text field style here and what we want is a default text field style so this is looking pretty darn good already and lastly we want a TL button remember that button that we had created to be reusable so we will have a title here of save and maybe we will use Pink as the button and then we'll have an action in here and this action will probably trigger something on our view model something along the lines of let's do viewmodel dot save we'll want to create that function there since it doesn't exist yet even though we will be implementing it much later on all right so let's do command B make sure that we are able to build so we have this pretty nifty looking view here as soon as it loads but we don't really have a way to present this yet let me also stick a padding off this make our button a little more uh breathable in terms of spacing there so let's jump back into our simulator when we tap on uh the plus button up here we want to basically show this view via a sheet right we want it to be modally presented in other words to do that luckily Swift UI has a modifier that is super creatively called you guessed it sheet so a sheet can take in a binding for if it's presented or not and then content as well so for our binding here we are going to say view model and we are going to say showing uh new item view just like that and essentially this is going to be a published property off of The View model that we've got here so we'll say at published far showing this and by default it's false right because when our app first launches and gets to the screen we don't want this to be shown right away and the content that is going to be shown is our new item View so go ahead and hit command B to just compile make sure everything is working let's give our preview wave run now let's give this a run in our simulator and tap on this plus button all right so something weird is going on we're not actually showing it ah and I see what I forgot to do when we tap on the button we actually want to set this to be true so here we will say viewmodel showing we're going to set this to true all right let's give it a shot for the second time hopefully when we tap this now we should see that other screen beautiful we do indeed see it so our new item uh label at the top is a slightly bit ugly because it's so flush to the top of the screen so let me jump into that view and let's take care of that so we'll jump into here and on this perhaps we can add a little bit of padding and if that's not you know sufficient we can always adjust the top padding in particular but I think what we'll want to do is just change the top so I'll change top and maybe make it 100 which will push it down from the top 100 points okay cool looking a little better in light mode in dark mode it looks pretty nice we can type in a title here so maybe we need to get some milk and I can select one of these dates as well as I have a nice time picker for hour minute as well as AM and PM okay so we're not going to actually work on saving this quite yet we do want a way to dismiss that screen so you just saw there I can actually swipe it down but it would also be great if I can get it to go away once we hit the save button um presumably we'll want to do that once you know the user has actually hit save and we have actually gone ahead and saved that result into the database so what I'll create here is a binding that we need to pass in and this is going to be a new item presented and we're not going to actually have a default value for this it will be of type bull but rather what we'll do is wherever we're creating this view you'll see and this is our to-do list view that it actually asks us go ahead and pass in your new item presented binding and what we can do here is simply pass in viewmodel that's showing new item view let me just hit command B and make sure you prefix this with a dollar otherwise it'll yell at you like it just did for me and let's see why this is yelling now it is actually yelling at me now because we need to do the same thing for our preview here so in our preview I'll go ahead and say binding with a wrapped value so let's see getter and Setter I guess we can do it this way we'll make this simple so in this case we will return uh true and for the setter we'll just do nothing and that should be sufficient let's see if our preview still works sometimes um if you don't set up your Swift UI previews appropriately they don't decide to load but in our case they do so cool so we have this button here in our new item View and whenever we try to go and save a new element assuming it did save correctly we can also now say because we have this binding in here we can say new item presented and we can set this guy to false which should trigger our view to go away so let's give this a shot in our simulator I'll get this presented I'll hit save and boom it disappears beautifully just like that the last thing that I want to address in this video is some basic validation of inputting stuff on the screen and more importantly handling um that validation and if something goes wrong right so showing an alert to the user if they're trying to save without a title or if they're trying to select a due date that's older than today so on and so forth so what I'm going to do here is inside of the save functionality Under The View model what I'll do here is I'll say VAR can save and we're basically creating a computed property here in which we're going to check a few things we are going to first say guard that the title isn't empty else we'll say hey return false we'll also make sure that we're going to guard title that is trimming in the white space character set that way we don't want to go ahead and actually allow the user to save just a bunch of spaces and tabs the next thing that we are going to do in here is we're going to say make sure that the due date is greater than or equal to today minus 86 400 seconds and I'm going to explain that in two seconds alrighty we're going to return false otherwise so by saying due date is greater than today which is just date that makes sense right make sure it's greater than or equal to today the problem becomes that uh this date is initialized to the current uh date like the actual calendar date in my case it's April 30th but also the hour and second and we get into some time zone complexity so what we actually do is we're subtracting 86 400 seconds and you might be wondering what on Earth is this number this is how many seconds exist in the day so we're taking the current date and just subtracting um 24 hours and we're saying make sure the due date is greater than or equal to yesterday so in some cases you will be able to pick yesterday but this will allow you to pick today and not run into any weird issues it's a pretty nifty little Edge case but I'm just gonna do it this way for the sake of simplicity Okay cool so now that we've got that there before we try to save a new element right away what I'll do is I'll say if viewmodel can save do that otherwise we want to show some sort of alert and the way we'll do that is by saying viewmodel dot show alert will be true and I and I realize that show alert does not exist yet so not not to worry so let's jump into our view model here and like we did for so many other published properties let's create a new one this is uh going to be called show alert and by default it will be false now back inside our view we're gonna use a very conveniently named modifier and you guessed it it's literally called alert and alert we're going to use a variant that has a is presented and a Content so the first one actually and this will be a viewmodel that show alert and in the content we're basically going to show the user a alert with a title and a message so let's do title is going to be error and message is going to be please fill in all uh fields and select due date and newer than uh today or newer I guess let's report this so it's like the dvdate that is today or newer so let's give this a built-in run and let's see if we have any issues um it looks like we already have an issue and that issue is that our message here should probably be a text if I was to be a guessing man so let's change these to text AKA labels I'm also going to line break this so we can actually read it a little better and let's give this a build and run let's try to save a new element without filling anything in here so I'm going to hit save and I should get yelled at and it should not dismiss which indeed we do now let me type in an element let's say we need to buy some buy some milk and let's buy some eggs instead eggs are expensive these days everyone needs eggs so let's buy some eggs let's say we got to do this tomorrow May 1st and maybe I'm a crazy person and I'm gonna do this at 5 45 a.m when no stores are open so let's do that we expect to see this view dismissed because all the fields are valid so if I hit save it does indeed dismiss so that is all we've got in this video let's do a quick recap because we actually did a lot we created the UI for this new item View and the way we did that is by creating a form that we've got right here we also have this text at the top inside all this is inside of a v-stack so it's vertically oriented and nicely nested we also created a view model with some basic logic functionality to verify that we can indeed save the data and can save in the view model here is checking that we have a title set that's not empty and that our due date is inappropriate range of today or after and then save isn't doing anything yet we also back in our view for the to-do list view we leveraged the sheet modifier and we created this is presented via a binding and we present this new item view so that's how we're going to get this to show up and get it functioning in the next video we're going to start working on actually saving and creating these to-do list items getting them to show up here so on and so forth so hit that like button before clicking away if you've made for our kudos to you for keeping up and staying with uh stay in the course with this series appreciate you watching and I will see you in the next part welcome back to the next lesson in the Swift UI to-do list app we're going to continue uh where we left off basically in this video we're gonna start to save new to-do list items to our database we're going to talk about the model etc etc before we dig in Destroy that like button down below as per usual and let's continue so we set up our new item view for creating a new to-do list item with a due date as well as a due date rather as well as a title I should say so due date and a title let's jump into that view uh it is our new item View and we also set up a view model with a save button basically a save button as well as a safe function that is tied to it and this is in our new item view view model so what we're going to want to do in here is import both Firebase auth as well as import Firebase firestore AKA our database now once we hit save we're going to do two things we are going to say guard can save now this is something that we should have already checked for in our views logic but we'll just stick it here as another you know sanity check and what we want to do is create a new instance of a to-do list item model from the supply data we have our title and our due date once we create the model and let's actually stick in comments while I blabber on so we're going to create a model once we create a model we want to save the model to the database and the way we're going to save it is basically as a sub collection of the current user so we'll also want to get the current user ID here right because if you recall in our database the way this works is we have a collection called users we have a user ID and then sub of that we would have a collection called maybe like to Do's or items whatever you want to call it and that's where this new element would go into so we also are going to put a comment here of get current user ID so let's do all this one by one so getting the current user ID is actually pretty simple we can actually say guard let uid is going to be off from Firebase auth.auth current user dot uid else we are going to return so we know that the user was signed in which is how they've even gotten this far so we should absolutely always have a user ID we're just going to read it off of the Firebase auth context so now that we have that we want to create a model but we haven't defined this yet so let's skip that for a hot second now in this case we want to or the last case I should say is get an instance of our database and say database with a collection of users now this should have a document of our user ID another collection off of that called maybe to do's another document off of that and this should be whatever our new model ideas let's call it one two three for now and then we want to set data for this and this is going to be a dictionary and that's basically how we're going to save a new to-do list item now obviously we glossed over the most important piece here and that's creating our new item model we have an empty Swift file called to-do list item under models let's open it up and declare a to-do list item model in here so already so I'm going to create a struct and call it to do list item it is going to be codable and it is also going to be identifiable and we're going to start sticking some stuff in here so we're going to have a string type for ID we're going to have a title basically what the user types in for the item we'll have a due date of type time interval we'll have a created date of type time interval as well this is basically when the user has actually created the element not when it's due per se and we're going to have a variable that is going to be is done of type Bull and the reason this is a VAR is so we can actually mutate this now this object is also going to have a mutating function on it called toggle done maybe is what we'll call it or maybe what we can do is say set done and we can call this state Bull and essentially inside of here we'll say is done is State and the reason that we need this here is once we bring in the functionality to check or uncheck if a item is done we are going to want to modify the model to reflect this before we save it or update it in our database the reason this is mutating here is because this is a struct structs are value types and if you're not familiar I've got dedicated videos on this as well so hit command B make sure things are still building and let's come back to our view model where we're going to instantiate this new item so we'll say new item is a to-do list item and it gives us all this nice jazz here so let me just line break it to make it look a little nicer and more readable and we'll start filling all of this out Okay cool so we're going to create a new ID up above it's going to be a uu ID and we'll get the uuid string from it this is just basically a unique new identifier that is what we will use for our ID Le is title due date is going to be due date and we're gonna get the once again time interval since 1970. created it will be now and we're also going to get time interval since 1970 and by default every item is not done so we can just hard Code false into is done now that we've done that here we're going to use our new ID in the database and the data we're going to set on this is new item and remember that handy function we wrote called as dictionary well boom we're going to use it again here to convert this model to a dictionary that we can write into the database hit command B everything should be building let's go to our browser here we just refresh it real quick before we try to insert an element and let's hit command R to build and run this in our simulator and let's give this a shot so we're logged in here we'll hit the slow plus we're going to say let's call this and buy some more eggs with an exclamation mark because supposedly that's exciting we'll say May 1st and I'll hit save here so it looks like it did dismiss we don't see obviously anything here because we haven't done much in this view but if I come back to our database under this user we should have a new collection called to Do's which in fact we do it should have a new single element with some random ID with all the data that we have indeed saved so we've got that is done as false buy some more eggs with an exclamation mark we've got the ID and the due date and created date we're respectively As Time intervals so awesome we're finally saving to-do list items and the flow of creation is basically done what's left to do is actually fetch these out of the database be able to mark them as done or not done delete them and then of course this profile tab over here where we'll also be able to sign out so that is all I've got in this video as a quick recap we basically implemented this save functionality here we get the user ID off of the Firebase auth object we created a model here which is representing a single to-do list item entry and we basically insert it into the database just to take a quick peek a revisit of our to-do list item we have some constant properties on here we have a variable for is done which is mutable AKA we can flip the value of this true or false and we have a mutating function to act actually a sign is done which will make a copy of this model that's how value types work and return that copy to us with the new value so that is all I've got in this video appreciate you all watching destroy that like button before clicking on to the next lesson and I will see you guys there welcome to lesson 10 of the Swift UI to-do list app Series in the last part we were successfully saving new entries new items to our database and in this part we're gonna finally fetch them and query them out in a real time way such that when we make new entries we also see them so hit that like button before we dive in and let's do it let's dig right in so what we want to work on in this particular video is our to-do list View and we want to actually get our elements our to-do list items to start showing up kind of important so I want to call your attention to our initializer here we're passing in the user ID and I briefly mentioned that we're gonna need this but I didn't quite clarify why we need it well the reason we need it is because firestore our database has a handy uh property wrapper some functionality where we can actually say hey observe all the entries in a database at a particular path and when I say path here what I mean is our data that we care about lives at users the user ID to do's and then basically all of our entries right so n number of to-do list items well this user ID actually fits in right here right it's the user ID specific for whom we want to get items this is why we actually need this here so what we'll do up here is we actually first want to import firestore Firebase firestore Swift and we're going to create something up here called a firestore query we'll say this is VAR items and it's going to be a list of to-do list item and this is the model that we basically used to create a new item before we converted it to a dictionary and stuck it in our database so we're essentially saying that we're going to have a query that'll continuously listen for items now this is now yelling at me with an error because it's saying well hey you have not assigned items yet we can't actually assign it up here with a hard-coded value because this is going to differ based on whatever user is signed in and this is where this user ID comes into play so what we can do here is say self that underscore items the reason we're using underscore is this is the convention for property wrappers and this at thing is a property wrapper up here and we can actually say that this equals a fire store query and we care to create a query with a collection path and it's going to be this collection path right above that I've commented out so it's going to be users then we're going to stick in the user ID slash to do's and we can actually get rid of this user ID here like so so this is our items if you hit command B it should hopefully be building the other thing that I will do is down in our preview content we stuck in just an empty string which is not good no bueno because it's not going to actually render anything because that ID isn't real so what I will do is from our actual database I'm going to copy our unique user ID that we actually have created and inserted into the database that way when I do command shift p we should hopefully get a preview rendering here so now that we've got this items presumably working we should be able to Loop over these items and show a element for each entry so let's create a list over items and we're going to have item in and let's just start by doing a text and we'll say item dot title I will also say list style will be a plain list Style and just like that it's actually quite fast you already see we see buy some more eggs get populated so that's pretty darn cool already now we're gonna want this row to look a little bit nicer we're going to want maybe the due date below it we want maybe a little check mark on the right of it and this is why we actually already created another view which is a to-do list item view this represents a single item and this is where we will encapsulate all that logic now this gets created with a to-do list item just like that and we will probably want a respective view model for this as well momentarily but let's just handle setting this up so we're gonna have a horizontal stack inside of here and we want to make sure we spell that right and we're going to then have a vertical stack now our vertical stack will have two text labels the first one showing the item's title the next one showing the items due date but rather than showing the due date directly what I want to do is create a date element time interval since 1970 and once we have created this here we want to actually also format this so I will say dot formatted and we want to format this with a appropriate date and time so the date here perhaps we will format this with abbreviated and for the time we will make this short end so this will actually take your the date object and make it look a whole lot nicer let's see what else we want to do we'll want to have a spacer and let's just hit command shift p to see this in action just so we have something here it wants a dummy item so let me create one here just to work with we'll say ID is one two three title is get milk maybe we'll have a due date is the current date time intervals since 1970. and created will basically be the same thing and is done will be perhaps false so I'll say command p to see our preview here one more time and let's see why this is yelling at me we need to have some parentheses for our spacer and let's preview what this is looking like so cool we've got this vertical stack here it looks like it is centering both of these text labels so I am going to say alignment here is leading and hopefully that looks a little better okay looking a little better we probably also want our font size to be a little bigger for the actual item I'll also bold the actual item and for this one here I will say the font here will be a footnote and in this case the font here will be let's try title and see how obnoxiously large that is and if it works all right it's not actually too bad we probably also want this to have a foreground color that's a little lighter so maybe like a gray color is sufficient but let's see if that looks too dull it's slightly dull so it'll actually go with here is we can use a UI color and what I'm going to look for is a secondary label this is basically like a lighter label color and we can actually probably get rid of the Bold color here all right cool so the reason we put this inside of a horizontal stack is on the right hand side of this is we want a button and this button should basically be untappable to mark this element as done or not done in the label the actual case of what we're going to show here it's going to be a image with a system name and the system name is going to essentially be if the item is done we are going to show a filled in circle otherwise we are just going to show a normal Circle so here we're going to have a circle dot I believe it's checkmark dot fill let's see if I remembered that correctly all right we'll do command shift p and let's set our is done in our preview to be true and make sure something shows up it looks like nothing does so it might have been check mark dot Circle dot fill okay it looks like that's correct and just as a reference you don't need to be guessing these if you hit this little Plus at the top right of xcode and then you actually hit this little icon you can actually search for all of Apple's iconography in here there's also a dedicated SF symbols app to search for various icons but I just happen to remember hence why I'm guessing so awesome so we've got that check mark there um the view is kind of smushed to the edge of the screen I don't think that's a problem though because when we end up using it in our list that will actually I guess just do now it should look better so let's create this with an item which is an item and because we're in a list things are looking better now our font looks really wonky so let me get rid of this and let me actually make it maybe we'll make it like body and see if that looks a little better because that title was a little large otherwise perhaps we'll specify our own uh titles here so I should be able to click on this button here and something should happen right now nothing is happening but at least this view shows up I should be able to also swipe on these rows so to do that we're going to add a swipe action modifier and swipe action will basically just have a button in here and the button will be delete and let's see if we can actually swipe on this I believe that's how we can get this to work yep um we probably want it to be red since it would look a tad bit nicer so let's actually use a different permutation of this button we want the one with an action which will be to delete and the label here we will go with delete with the foreground color of red so it looks a little more panicky since you are deleting something we want to make sure that's your intention alrighty hit command B make sure everything's looking good already let's try that one more time it looks like it's still not red let's run it in a simulator let me see what it looks like over here all right so it's definitely not red let's see why that's happening let's try background color here perhaps that's what I'm looking for and it's still not red hmm okay let's see what's going on so we're gonna we're gonna debug this together so let's actually change this back to what I had here as a standard button and let's make this color dot red and I could have swore this should turn red that way but perhaps not so we might have to come back to this uh and indeed debug it but I could have swore this is how we I've gotten this to be read before but anyways we've got our to-do list items rendering here um when I click on them nothing happens when I hit delete nothing happens we eventually well I guess we can stick it in right now we're going to want to implement this function which is delete uh an item so we're going to say funk delete item and this should be to do list item just like that or maybe we'll just pass in the to-do list Item ID and whenever this button is tapped we can say view model delete item dot ID like that and similarly we've got that button with the check mark here as well so what we'll want to actually do is whenever we tap on this check mark button we'll want to say view model dot uh update check or set or toggle check mark something along the lines right so basically flip the check mark if it's checked uncheck it if it's unchecked check it so we'll say toggle uh is done is I guess a better function name here I don't believe we have a view model for this yet let me see if we do I think actually we do I remember creating it and having different names for it so we do have this guy here let's stick this function on here and let's go back to our view here so this is in our single item so we want to do list item View and we want to create an instance of this state object or of this view model I should say as a state object so now that we've got an instance here of our view model we should be able to say toggle is done item is item we'll want to pass this in I don't want to implement this in this video but I at least want to stub out these functions that way we have a nice jumping off point as we continue so this is where we will mark this and if this item changes of course we should indeed see our UI update as well so I guess it's a good stopping point for this video we now actually have our elements showing up in this to-do list and the gut check to make sure it works properly is let's add a new item so we're going to say finish up video we're going to stick with today since that's probably what we're doing today and I'll hit done and boom we see finish up video did indeed get created for April 30th at 6 34 PM which is indeed my local time here on the east coast of the US so awesome kudos to you if you've gotten this far the app is more or less functional now I hope to see you in the next lesson hit that like button before jumping on over there I will see you guys there welcome to lesson 11 of the Swift UI to-do list stuff we're gonna continue working on this app we finally got our items showing up in the last lesson in this lesson we're going to focus on deleting items before jumping in hit that like button and let's continue so in the last video I couldn't get the delete button when we swipe on over on an item to be read and I realized one second after ending the recording of that video uh what mistake I was making there so let's actually go and amend that so we don't want to actually change the background of this button what we want to change is the tint of the button so if we change it and we make it red and you refresh your preview with the command option p and you drag on over you'll see that we now have delete here so beautiful let's actually get this deletion working so we already created a function called delete on our view model where we're passing in the item so we should be able to Simply make this database deletion call so let's import fire a base fire store and let's actually get a reference to our database by saying Firebase rather firestore.firestore and then we'll say database.collection in our users in our document we want to put the user ID here which we'll do in a second we'll talk about that in our collection of to Do's we should have a document with a document ID that we're passing in and we're going to Simply say hey go ahead and delete that we don't need any callback because our firestroke query in our view is listening for live updates in our actual collection path everything should just seamlessly update and be magical alright so before we can actually give this a run we need to put in a user ID here well there's two options we have we can pass this into our delete function but that doesn't really make sense because then we have to hang on to user ID on The View well but we're already passing the user ID via our Constructor into this firestore query so how do we actually get it into our view model we can of course get it from the Firebase auth like we did elsewhere but that's kind of redundant so let's let's think of a better way to do this so instead of creating this state object like this what I can actually do is I can Define it here and we can actually assign it similar to how we're assigning items here we can specify that our Constructor here is going to take in a user ID I will say self.user ID is user ID for our view model and we're essentially going to instantiate this view model for the state object in the Constructor so we'll say self underscore once again that property wrapper semantic is going to be a state object with the wrapped value and the wrapped value here will be our view model concrete class the user ID is user ID so let's see if I can get this uh get this cleaned up a little bit in terms of line breaking because it's a little wonky right now all right so that's basically what we want to do so what we're essentially doing is is instead of creating the view model um as a stored member on this view we're going to create it by creating a state object like so and passing in that view model with the associated user ID that we're getting through this views initializer hopefully that's not too confusing the syntax might be a little confusing but more or less we're putting the user ID into this view model awesome so now that we've got the user ID in here we can actually use it in our deletion call so yeah that's basically all there is to it good practice we're gonna hit command option backslash to get this autocomplete for documentation and we're just gonna add some docs and comments here this is going to say delete to do list item let's make sure we spell that right and this is going to be Item ID to delete just like that and uh let's see if we can get this working all right let's build and run to the simulator let me add in a couple elements here so maybe we'll say go running we'll save this guy we should see it pop up maybe we'll also come in here and say uh buy a jacket because it is indeed raining out and I could do it with a new jacket also going on vacation soon so maybe we can say plan Vacation Fun things I really save that all right so we're good to go so let's try deleting some stuff so I'm gonna say let's say we already bought some eggs so we don't need this anymore so I'm gonna drag this over and hit delete and boom it's it's gone so let's try to close and reopen this app and that should not come back all right so definitely does not come back let's delete the rest of these alrighty alrighty let's delete all of these apparently I'm done with everything that I needed to do because there's nothing left here let's close the app and reopen it whoops that's the other version of the app let's open this one here that we're building and nothing indeed comes back so we've successfully set up deletion of to do list items just to recap we pass in our user ID into our view model for the to-do list View at this point we've implemented the delete function to more or less just delete the record at the path of users user ID to do's and then the idea of the to-do list item that we would like to delete back in our to-do list view we now assign the viewmodel rather than having it already created up here it is a state object where the wrapped value is our view model type passing in the user ID we amended our button in the swipe action to use a tint rather than a background that's how we actually get it to show up as red and we finally got deletion working so that is all I've got in this video we are going to work on hitting that done button the little um check mark on the right of an item in the next part so let's actually end this video with a new element here so we want to get the groceries not Grocers so let's create that we'll make this little circle over here interactive in the next part so I'll catch you all there welcome to the next lesson in the Swift UI to do app series and in this video what we're going to focus on is basically getting this uh check mark working on the right hand side here so basically marking things as done or not done so let's continue before we get into things smash that like button down below and let's continue so we already got swipe to delete working here so if I swipe this and hit delete boom it's gone let's create a couple items so I am going to say get milk here and maybe we'll create just two to get started with and then we'll focus on that little check mark so let's say uh go running because eating healthy and running is supposedly good for you so I will add it there so awesome so we've got this like circle thing here and essentially that is a part of our item view for a single to-do list item and what we are showing is a image and if the is done property on an item is true we showed the check mark with the filled in circle otherwise we should just the circle now we want to do two things here the first thing is we want something to happen when we tap on this particular button so right now we actually already have it hooked up to be uh toggle the other thing we want to do is we want to validate that the UI updates properly once we update our database record so let's let's do this first so we say toggle is done and if you recall the to-do list item if we click into here does have a function that says set done that we can pass in a new state so what I'll do here is here I'll say new item is going to be our item so we're going to basically create a copy of it and we're going to say item set done and this is going to be item dot is done whoops is done we're going to set the inverse of this so in other words if is done originally is true it'll be false if it's false it becomes true the reason we used a new item here is because if we try to do this on item you'll see that it will yell at you because item is a constant it's immutable it's passed in as a value type so we need to create a copy of it which is why we just call this new item maybe it's actually more suitable to call that item copy not to confuse it so now that we have actually gone ahead and created this copy and changed it's is done property we need to update in our database the record for this to-do list item and to do so it's particularly easy so we need to import two things here so we're going to say import Firebase auth and we're also going to say import uh Firebase fire store that one right there we are gonna want to get the user ID like we have previously gotten so I'll say uid is going to be auth.auth dot current user.uid else we can go and hit return and we'll just stop next up we can save the database is firestore.firestore and I can now say database dot collections the collection we want to update is users and users should have a document which is the user ID which will then have a section for to Do's which should have a to-do item which is going to be our item copy dot ID once again we're not making a new item we're just updating the data for an existing item I will say set data and this will be item copy dot as dictionary so that should be good enough actually to get to our check mark working so let's give this a build and run in our simulator and let's see what happens we hit that check all right so I'm gonna hit this and boom it's checked and boom it's unchecked now what's actually happening here is Swift UI is updating our view in real time as a result of the model changing and the model that we are changing in the database once it changes in our to-do list view it's actually being read in our firestore query and we're getting the new version of the item so if I actually close this here and I reopen the app you'll say you'll see that when it opens it opens as being checked because we're basically saving in the database that hey this element should be checked it is indeed done right so we have some persistence going on there which is obviously useful for a to-do list app you don't want it to be reset every time you open it and lose you know all the information about what's done and not done the other thing that I want to quickly tweak on here before wrapping up this video is I want to change the color of that check mark so our check mark view what I will go and change here is the foreground color on our image you can make it whatever you'd like I feel like blue is a nice color for check marks so I'm going to make mine blue so we'll go and give this a build and run in our simulator make sure our check marks are showing up as blue beautiful they are you can use obviously any color I really like the way this looks and yeah that's basically the the meat and potatoes of a to-do list app we can create elements we can delete them we can mark them as done or not done you can also add some padding for each of these elements if you'd like just to space things out a little bit I recognize that it's a it is a little congested but you know to each their own of uh preference and how it should look but that is all I've got in this part drop a like down below below before clicking on to the next lesson let me know in the comments if uh you found this particularly nice that Swift UI takes care of a bunch of this heavy lifting for you appreciate you watching uh say hello in the comments as well connect on the socials I always love hearing from you guys and I will see you in the next lesson welcome to lesson 13 of the Swift UI to-do list app in this lesson we're going to work on the profile tab here since we've got nothing going on here before we dive in Destroy that like button down below and let's start building so we've got our actual to-do list working in this Primary Home tab but we want to show something in this profile tab as well particularly some information about the user as well as a way to sign the user out so we have a profile view here let's open it up and let's get to it now what do we actually want to show in here it would be nice to show an avatar image even though we don't allow the user to you know upload images and maybe a person Circle image and then we want to show some info about the user so things like their name maybe their email maybe member synths and then we'll also want to show a sign out button so let's start adding all of these so we're going to start with the image it's going to be a system name image or we're going to work with a person that Circle we're going to say it's going to be resizable we'll set a aspect ratio of fit so it always stays in the proper ratio doesn't get distorted or anything we'll set a nice foreground color of blue and then we'll also set a frame with a width of 125 as well as a height of 125 so it's a nice Square aspect ratio next up inside of here what I will do is create a v-stack where we have the alignments as leading let's get rid of this extra content thing there and we will create some horizontal Stacks now let's just get one to show up here so we know what this looks like but we're going to say the first text here will be name like so and then we'll have another label right next to it which hopefully will load in user data and be able to show the name so let me just copy and paste this a few times so we'll have a name email member since we'll want to obviously change the value on the right of it and then finally at the bottom here we will have a label and let's actually use a TL button which is our custom button that we've created our title will be sign out let's actually use the wording log out since we've used login elsewhere and our action here will probably want to say view model Dot log out which we don't actually have a function for this so we've got some work for us to do in this video so let me jump into uh this particular view model and something is wonky here we're using the profile view view model here and we have toggle is done inside of this oh no what did we do I think you screwed up something here so our profile view is actually being used or a profile view model it looks like is being used rather than our today item view model so let's see what is going on something is totally screwed up here but we're gonna fix it so here we have a today list to do item okay so we accidentally put the code for a single to-do list item inside of here which is not a problem not to worry we're going to take the implementation of this toggle function we're going to cut it with a command X and let me paste it into this guy now before I can send you on the profile Journey let's take the name of that view model let's come back to our single to-do list item here and let's make sure we use the proper view model there and before we try to build to make sure nothing is screwed up don't forget we need to add a log out function inside of here in the profile view model so it looks like we build built and we do have some problems here let's see what's going on yep we do need to import in here Firebase auth which is what we had imported in the other view model where I accidentally put the code that's okay we're going to import firestore as well and everything should be building okay so now that we've fixed that let's go back to profile and just give this preview a refresh command option p and we should hopefully see something here looks like we're not actually seeing it so let's see what gives let's give this a build and run let's see if everything is looking good let's go to our preview okay so in our preview we see our button here we see our information and we see our Avatar image at the top but this button is just obnoxiously big so let's see how we can go about adjusting this let me put a spacer below this and let's see if this looks any better otherwise we might fall back to the normal button okay so that button is still absolutely obnoxious so I'm going to create a standard button we're going to say this is log out and this button will have a tint color of red so let's see what that looks like all right okay so I think this looks a little better everything is a little smushed together so we probably want a little bit of spacing so let's actually do that we'll add a padding on here I'll also add a padding on here and even for the image up here perhaps We'll add a smidge of padding padding so let's give that a run again and check it out all right we're looking a whole lot better um maybe we want the labels here the left I uh the left label in each H stack to be bold so I'm going to stick a bold on each of these and perhaps on each of these we also want a little bit of padding so I'm going to stick a padding on each of these as well and see if that looks a little nicer something about a good amount of margin and padding just makes everything so much nicer so okay so we want to get this logout functionality working but the first thing that we want to do and more importantly is get the user's profile to load and show here so we actually would need to fetch this from firestore and we don't actually have it at the moment so what I will do is I am going to open up this view model for our profile and we're going to say we have an app published VAR user of type user and by default it's going to equal basically nil we don't have a user we're gonna want to fetch that user so let's create a function called Fetch and what we'll do inside of here is pretty simple we're going to say guard let user ID is going to be auth.auth dot current user dot uid similar to what we have done elsewhere now that we have this from the database firestore.firestore we can say hey in the collections of users get the document with this user ID it's what I'm looking for and we're going to basically say hey get this document now we say fetch a document we actually get a snapshot back and the error once we have that we're going to say guard let the data that we are going to read off of this query is Snapchat dot data like so and we'll just verify that the error indeed is nil once we have this data we can actually create a user object and assign it to this so we are going to capture weak selves so we don't cause a memory leak like I mentioned I'm going to gloss over this just to not go down and wrap the hole and we do want to do the following on the main cue since um assigning a user will indeed trigger a view refresh so let's create a user so we're going to say self dot current user which I just called to user in this case is an instance of a user and let's start filling all of this stuff in so ID name email and joined so we are going to say that this comes from data this will be ID and you just want to cast it to the appropriate type so it's string string string just make sure you update these and you don't have any typos and this one here is going to be joined as a time interval otherwise here we'll just stick a zero and this should be sufficient to fetch the current user now once we have the current user we can use it to fill out all the user profile information so by default we don't actually have this user so what we'll be able to do is the following I'm going to say let's take all of this Jazz and I can say if let the user is viewmodel.user we can continue otherwise we want to say show a label that says loading profile with a dot dot dot now once we have a user instead of hard coding my name everywhere we can say user.name user dot email and then this one here is going to be a date time interval since 1970 and this is going to be a user dot what I'm looking for is joined and we do want to format this with a date which will be abbreviated and a time which will be shortened alrighty we did a lot of coding there so let's give this a build and run and let's see it in action we expect to see this say loading and we expect it to load the profile but it turns out we never actually called that fetch function that we implemented inside of our view model so where we're going to actually Implement that is in a Handler in a modifier on on appeared so once our navigation view appears here we're going to say viewmodel.fetch user alrighty so let's give this a build and run and as soon as this appears we should hopefully fetch our user and we are good to go so there we see our name our email address as well as when we joined this awesome to-do list app so that's our basic profile we still need to hook up log out but one thing that I do want to do is I do want to at least abstract out this monstrosity of this view stuff that we've got going on here so let me take all the stuff inside of this if statement and what I will do is I will say this is profile user is user and I'm going to create a view Builder annotated function here called profile that takes in a user of type user returns some View and I'm just gonna stick all of that implementation in there which is going to just reduce our body looks which makes it look a lot cleaner easier to work with this error is just transient it should go away once xcode gets its life together there it goes so a little bit of cleanup so we do still have that log out button here and when we tap it we're calling viewmodel.logout luckily this is really easy to implement all we want to do in a do catch Block in the catch I am going to print out the error that should never ever happen but we will say try auth.auth and we're going to sign out you might be wondering well hey how are we going to actually show the login screen again well it's pretty simple actually because we already handled it if you remember in our main view view model we've got this handy dandy listener here this Handler for our auth state did change event and that should update our main view to show the login screen so let's try to log out and we'll see if this whole shebang actually works so fingers crossed everybody hold your breath all right boom so we are now logged out of the app let me give it a run make sure we are still logged out doesn't accidentally log us back in and moment of truth let's try to log back in to our account our super secret password is password and boom we are signed in it loads in our results we can update them we can add more results we'll say verify app let's pick a time in the future all right there's a there's a new date we'll change the time here maybe we'll go to uh an earlier time and I will save this and there is our results and that's basically the uh the majority if not all functionality for our Swift UI to-do list app now while it's super exciting we're not quite done yet we don't actually have an app icon yet if we look at this app on the home screen kind of ugly we also want like a nice loading image when we launch the app also known as a launch screen so one more video to go in terms of building this out appreciate you watching drop a like before clicking on to the next lesson and I will see you guys there welcome to the next and last lesson where we're actually going to be fussing around in our xcode project particularly focusing on setting up a app icon as well as a launch screen before we jump into things hit that like button down below throw a fire and a rocket emoji in the comments if you've made it this far kudos to you and let's get on with it so I've actually got this app icon that I created already I use canva to create this for free they've got a bunch of awesome resources there it's really easy to use they should totally sponsor me I'm not sponsored by them but check out canva I've got this dinky app icon but we're going to use this for our icon as well as set up a launch screen so let's get to it so the first thing we want to do is in execute I'm going to remove this from full screen let me also collapse some of these folders since we're just about done we'll open up assets here this assets catalog and you should have a app icon asset in here which tells you that it takes a single 1024 by 10 24 image and we can drag this in this image is indeed 1024 by 1024. now that we have done that we can just give this a stop and run again in our simulator and we should see our app icon appear now one common issue that people see with uh executed the simulator is you actually saw it right there is very fast but the icon shows up and just randomly disappears so if you actually delete the app from your simulator and just run it again to do it uh to install it fresh and go back to your home screen you should see the icon persist so that's basically setting up an app icon super duper simple just make sure you create an image that's 1024 by 1024 again canva is free to do so the next thing we want to do is set up a launch screen so this is a screen that you see while your app is in the process of launching now obviously this app is quite fast but sometimes based on the device and how old it is and battery and a whole host of things you're going to see an intermediate screen we actually saw it right there for a smidge second and that's known as your launch screen now the Swifty white template doesn't actually give this to you out of the box what we're going to do is create a new file that we're going to set as our launch screen so hit command n for new file and search for a launch screen in here leave the name as defaults and this will essentially give you a template which is a storyboard that looks like this you can actually use a drag and drop interface to adjust this as you'd like and back in our project Navigator if we scroll down here there is a section where we have app icons and launch screen and what we will do is hit this will drop down for long screen and you should see that newly created launch screen that storyboard file in here now we're not going to spend a whole lot of time designing this what I will do is change the title to be to-do list and we will change the background color by opening up the attribute inspector here this right panel we'll pick a fun color maybe we'll go with system purple and I'll also change the text color here we will go with white and I will also adjust the font to be let's see bold is perfectly cool with me I'll just bump it up to maybe like 44 and we're looking pretty good so let's give it a build and run and when our app is launching we should see that purple screen for a smidge we actually saw it right there and that actually concludes building a to-do list app entirely in Swift UI from scratch with Firebase so fairly straightforward if you think about it what did we do we did a lot of repetition in terms of the basic constructs we have a few within Associated view model with uh you know logic and whatnot in there to handle interaction of buttons and whether or not one view should be shown instead of another we also have models that represent the data types in our app in our case it's only a user and to-do list item and in other what we actually only adjusted was we added a single function which is the extension on encodable protocol this allows us to convert it to a dictionary and in our to-do list app we initialized Firebase here Firebase app.configure after we brought in our Google services info plist file which has all the information for our Firebase projects if you made it this far huge congrats give yourself a round of applause let me know know if you would like to see anything in this project change down in the comments source code will be made available for this project I appreciate you all watching and sticking around hope to see you in other lessons series and videos across the channel while we continue building and polishing iOS iPad Mac and watch OS apps thanks again for watching I will see you in another video
Info
Channel: iOS Academy
Views: 107,602
Rating: undefined out of 5
Keywords: swiftui beginners, swiftui tutorial, swiftui masterclass, swiftui basics, build first app, swiftui build app, swiftui introduction, swiftui build an app, build iphone app, build ios app, ios make app, swiftui design app, swift tutorial, how to build an app, swiftui course, free swift course, make ios app, xcode swiftui tutorial, swiftui for beginner, beginners swiftui course, how to make an app, make swiftui app, swiftui to do list app, swiftui app tutorial, swift app
Id: t_mypMqSXNw
Channel Id: undefined
Length: 162min 48sec (9768 seconds)
Published: Mon May 15 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.