Swift for Beginners: Create To Do List App (2020)

[Music] today I’m super excited to be going through a full beginner’s app build with you today we’re gonna be building a to-do list app with Swift and Xcode for iOS so with that being said let’s jump right in by starting up Xcode so we’re gonna be building this in Swift like I said let’s open up Xcode once we have it up here and let’s simulator let’s create a new project and we can do that by hitting command shift N and once Xcode decides to load which sometimes it takes a second or two we’re gonna select a single View application we’re gonna give it a name of two tasks actually instead of to do list let’s save it wherever we’d like and I’m going to basically be going through this step-by-step but we’re gonna create an app in which we can show rather enter to-do list entries show them when the person closes the app that comes back those entries are still there and they can of course go into an entry and delete it quite simply and I’m also gonna show how we’re gonna lay the foundation if we want to add more functionality like set it due date to it and set up reminders and things like that cool so we’re gonna explain every step along the way so let’s get into it by expanding our Xcode window to give ourselves some more room to work and first and foremost what we need to do is we need to go to our main storyboard and we need to set up our interface in here so we’re gonna essentially be using two view controllers one which is this one that’s already given to us and a second one we’re gonna display more information about a task that we’ve entered once we click on it we also want to show a list of tasks here so to do that we’re gonna use a table view so because we need these elements let’s start by dragging them in and adding constraints to them to lay them out so to do that we’re gonna hit this button up here which will give us our library of elements let’s search for a table view drag this in and once you see it on your view controller we’re gonna come down here and hit this button and this button will allow us to add constraints so we’re gonna add zero zero zero zero which will pin this once we hit enter to every side of the screen then all we want to do is we want to add in one more view controller and we can simply search new controller and notice there’s a couple in here but we just want this basic view controller so this will actually give us another screen similar to the one you see on the left and once we create a task and click on it we want to show this screen and the other thing we want to do is we’re gonna click on this and we’re gonna come up here and go to editor and then we gonna go to embed in and we’re gonna select navigation controller and when we do that you’ll see that this extra window thing popped up this is navigation controller and there’s an arrow from it to our main view controller and what a navigation controller is is essentially the skeleton in which you can put more view controllers so if you open up the Settings app on your iPhone and I’ll actually show you through Google images well let’s do the navigation controller is actually the functionality of this bar up here where you can show a title and some actions and when you click into something you know that there’s like the animation where we get like this back about in and just swipe it back that functionality is actually all built-in for us right into the navigation controller which is what we’re going to be using to navigate between the lists of tasks and the task information that we display on this view controller next we need to go to our view controller itself which was auto-generated for us at this template Apple gives us one by default and we want to do a couple things in here the first thing we want to do is we want to create an outlet for our table view and this outlet basically lets us control the table view on the storyboard that we just added by connecting this variable to it and what another thing needs to do is implement the table view delegate and datasource which supplies that data and handles interactions with the cells on the table view and we’re gonna do that with extensions so reading through extension your controller delegate and we can copy and paste this real fast do data source in this implementation we want to handle taps on a cell which is gonna be did select row at index path once we’ve selected a row we want to unselect it in other words get rid of the highlight color that pops up so we’re gonna say table view deselect the row and this index path and the animation will say true this index path comes in from this function as you can see which is basically the position in the table of where that row is we have an error down here because there are two required functions that we must implement for the datasource and those are the number of rows as well as a cell for the actual row so we’re going to do those in just a second here before we do that what we want to do is let’s go back to our storyboard and do a couple more things on here so we see we have this table we’ve created an outlet so we need to right-click this view controller and drag from this connection outlet on this table view that we added to our actual table view and you can see highlights in blue because we can connect it and once we let it go you’ll see that there is this connection from this table view variable to our actual table view itself we also need to add a prototype cell to our table view which is more or less a template cell that we can reuse over and over to display information which in this case will be our title of the task that we as a user are adding so if you click on the table of you come up here open the side inspector this prototype cell you can see is set to zero let’s click this and make it one once we’ve added a prototype so we need to give it an identifier so select it on the left come up here and give it an identifier so I think it ain’t selected yeah so let’s open this up select the table of you cell come up here and give it an identifier and let’s call it just cell a maker looks simple if you have multiple prototype cells which I’ve gone over in another video in this case it’s a little irrelevant for the breadth of knowledge you need around it but if you do have multiple table view cells the identifier is do need to be unique next we can go back to our view controller what we can do here is we can say we need to create an array and this array is gonna hold all the tasks that the user has entered thus far which is going to be an array of strings we’re gonna implement the two functions that it’s yelling at us to do here so the first one is number of rows and we want to return the number of things in our task array that we put up here so obviously when we start and create the task array first and foremost it’ll be empty so in this viewdidload what we need to do is get all current save tasks which will fill out in just a moment excuse me the second thing we need to do is actually return the cell for the given row and we’re gonna do that in a function called cell for a row at index path and what we need to do in here is we need to DQ a cell which is something that a lot of people find a little confusing D queuing a cell more or less just means using the template over and over to get a instance of a cell and that we’re gonna configure the cell which means we’re gonna supply the data into a cell so when you open up like the Settings app every CEL has an icon in a text label the cell itself is the same reused over and over with the text label an icon being swapped out in our case we’re just gonna swap out the text of the actual task we want to display so we’re gonna do that by saying let’s sell equals table view dot DQ cell and we want to select those first one which is D queuing a cell with an identifier which is cell which is the one we gave in our storyboard and for index pass at the end here we want to return the cell in this function because it’s this function requires a cell to be returned to it in between here what we want to do is we wanna say the cells text label and its text is gonna be the text in that position in the tasks array tasks array and this index path row represents the position of the cell in our table view so for at the first position we want the first task and this function will only be called for as many cells that are in here so there will never be a situation where these two functions are out of sync in terms of count if we return the task count in here which is initially zero because this is empty we won’t return and call this function and return anything because there’s nothing to return cool so let’s actually run this app and see what we have so far what I expect is we’re gonna have a empty table view with no cells nothing on it because we don’t have any tasks yet the next thing we’re gonna be doing is writing the components to actually add a task and show it or add a task and save it rather into our application so we see we have this table view here and you can see that with the lines well I don’t know if is visible but anyways we’re gonna add a plus button up here and to do that we can simply do a storyboard actually so what we can do up here is come to here this library search for a barb an item we can drag it up here let’s give a title of AD let’s go back to our viewcontroller and let’s create an IV action which is gonna handle once we click on that button we’re gonna call it did tap add once the user taps ad we want to do something in this case we’re gonna show another view controller to make an entry so we’re gonna actually need another view controller so initially I mentioned we need to we have three here because one of the navigation but we I said we needed two because one is gonna show a list of tasks one is going to display task information and options to delete it and the third one we’re going to add is gonna be the one where we actually make the entries for our tasks so let’s find a view controller drag it on here and go back to this what we need to do is because we have this class for a view controller with all the code for this particular one that shows a list of tasks we need to create two more view controllers one to show information about a task and the other one to actually enter a task so what you want to do is right click this folder hit new file hit enter reading created cocoa touch class make sure this is Swift make sure this is UI view controller and the first one we’re gonna create is entry view controller as the name implies this is where we’re gonna actually enter in our task so we can go ahead and firstly delete this commented code that we give us that X 2 gives us right click it again new file one more time cocoa touch class and we’re gonna call this next one task of U controller where we’re gonna actually display info about the given task delete this once more now let’s go to the entry view controller in here what we want to do is have a field where the user can enter in a task and a done button function which once they click it will save it so we’re going to say IV IV outlet and it’s going to be a far field text field we’re gonna set a delegate on the field basically once the person hits the enter key in the keyboard will also prompt the app to save whatever is entered if anything is entered so by having this delegate we can come up here and say you wanna text field delegate well we can also then say is should return which is the function called once the person hits the return key on the keyboard and we’re gonna call a function here called save task which we haven’t created yet let’s create this and what we need to do now is in our storyboard connect this new view controller so this is yelling at us because we’ve said the field delegate but we haven’t said itself but we need to connect this view controller this code to an actual view controller so you saw that we dragged out another view controller here but we need to actually do is click on one of them one of the new ones come up here and in this tab give it the class that is associated with it so this one is entry the other thing needs to do is give it a storyboard ID which is the ID we’re gonna use to actually show the view controller the next thing you want to do is do the same for this guy we’re gonna give it the task view controller identifier that we created and give it a task okay cool so now let’s go back to our normal view controller the very first one ignore my antivirus pop-up in this function where you can instantiate that view controller with the ID we just created the entry view controller so we’re gonna say VC equals storyboard instantiate if I can spell instantiate today we want to instantiate viewcontroller with identifier and we can say as entry view controller now that we have our entry view controller here we’re going to give it a title and we’re gonna present it onto the screen and way we do that is we’re gonna say VC dot title we’re gonna say new task and because this main view controller we embedded inside of a navigation controller we can say a navigation controller push push view controller and give it the view controller you want to push animated true so let’s run this really fast go to our simulator and we’ll see that once we hit this add button and once this decides to move out of the way we’ll get the add view controller and the reason we’re not getting it is because I forgot to connect this function to our button so if we come back here click on this view controller right click we’ll see we have this function here that we created we want to connect this to this button what I’ll also say is come into here and give this entry view controller a different background color so we can actually see it in action so we can give it a black color for now let’s run it one more time and we’ll see that once we select this add button we actually crashed so why do we crash so we crash ah because we created a field in here in our entry view controller and we did not create it in our storyboard so similar to you guys I’m not going to edit these these little like dot J’s out it’s very common to have these little gotchas and it’s totally ok as long as you understand what you missed and go and add it so we’re gonna come here we’re gonna find the UI text filled it we’re gonna drag it on to our screen this is going to put a field on to our screen that we’re gonna enter the task in we’re gonna add some constraints to it so we’re gonna say 20 from the top 20 from the right 20 for the left and right and the height itself we’re gonna give it 50 to enter let’s right click this up here and let’s drag field to this run it one more time and hopefully we didn’t miss anything this time come up here and we can hit this Add button and just like that we have this screen pop up which is awesome the next thing I want to do is add another button up here two hits two called save to actually tap to save our task so let’s let’s do a couple things let’s go back to our view controller and give this you control a title as well so we want to say self title tasks we actually forgot to do one thing with our table view in here we specify this datasource and delegate but we never connected it in terms of saying our table views delegate itself and our table views data source itself we’re gonna then go to our entry view controller what we’re gonna say in here is we want to create a button at the top right which has the word save on it so you saw me drag on a button here to add I showed you how to do it in here we’re gonna actually also do one programmatically so you understand that you can do it both ways so go back to entry your controller and we’re gonna say navigation item dot write bar button equals UI bar button item and we’re gonna initialize it with a title we’re gonna call it save the style can be done the target itself which is where the function resides that we’re going to call and we want an action function we’re gonna call it and we want to select her in here actually a selector is basically just a way to reference a function in this class that we want to call once the actual button is clicked and we already have this here so we’re gonna paste this in here we can actually get rid of that IB action because we’re not we’re not connecting this in the interface builder or a storyboard we also want to put at Objective C here or at objc and that actually allows this function to be used as a selector in here what we want to do is actually save our content of the field so we’re gonna say rather we want to first make sure that the field isn’t empty so we’re gonna say guard field dot txt or we can say rather garlotte text equals field dot text and text is empty rather text is not empty so we’re saying we want to make sure that there is text in this field if the Rays it’ll come in to this variable and we want to make sure the text we’re checking if it’s empty and the inverse of it so we’re checking if it’s not empty if any of these cases match we don’t want to continue we’re just gonna return but once we pass this asgard statement we basically want to save our task so how are we gonna save to save the tasks in this app we’re gonna be using user defaults user defaults is a pretty lightweight mechanism built into iOS to save pretty simple of things it’s by no means a full-fledged database which is a little more advanced and a little more involved to setup but what we’re gonna save is two things essentially we’re gonna save a count of how many how many tasks we have so far and we’re also gonna save each task with a given number so the first time the app loads up nothing is saved so actually we want to come to our view controller and we want to set up the initial saving mechanism and let’s call this set up what we want to do is we’re gonna say user defaults dot pool four key we’re gonna say if this isn’t set up in other words if this is false we want to set up some initial default so by default we have zero tasks so we want to save zero so we’re gonna say user defaults set we want to set first and foremost a pool for this setup because we want to only come into year one so once we’ve set up on the first launch we won’t ever come into here again and we also want to say set a value for a key and that value is going to be a zero and basically let’s see if we can actually pass him a direct zero which I believe we can yeah so we’re gonna say set zero for key and it’s gonna be count which is going to be the number of tasks that we currently have so now we can go back to our entry view controller when we want to save this what we want to go ahead and do is get our account increment the number by one so we can say we have more things in our table view or in our tasks now and we also want to save the tasks that we entered which is in this variable called text so the first thing you want to do is get our account which is user default value for key they called it count and it’s gonna be an int and we should get a warning in just a second yeah because we haven’t actually used this variable and that’s what the second warning is here it’s also initializing as an immutable value but was never used yet basically says this warning is just saying that we created this what never used it this is an FYI if you guys are concerned of what these warnings are on side the next thing we want to do is actually change this to a var because we want to increment this so let’s say new count this count plus 1 then we want to set this new count again so we’re gonna say set new count for a count and lastly we want to actually save our tasks and the way we’re gonna save it and let’s see why is this complaining this is saying we can’t add 1 to this because it’s an optional so what we can do is we can say we can say I’m guard let count equals this otherwise return so the reason is giving us this error or it was a second ago it’ll go away is because when we try to get this count it might come back is nothing because Swift isn’t aware that we’ve already set this up in the other view controllers we have to just explicitly guard against it being nil in other words being empty so that’s all that warning means anyway so now we’ve updated our account here and the last thing we need to do is actually save our task and the way we’re gonna do that is we’re just gonna call this again except the thing we’re saving is text and the actual key we’re gonna use to save it it’s gonna be task underscore our new count so each key every time we save this new task will be unique and that’s how we’re gonna save last thing we want to do is a little confusing to wrap your head around while the concept is pretty simple but the actual implementation is a little confusing but what we want to do is we want to not only remove this screen but we want to update the table view on this previous screen and to update it what we’re gonna do is we’re gonna pass in a reference of a function to this particular view controller so what that means is we’re gonna create a variable up here let’s call it update and the type of this variable is going to be void returning void and I believe this means to go into parentheses like so and what this does essentially and this is complaining because I guess we don’t need these actually just kidding so what this actually does actually we don’t even need that at all I believe we can just do this as swift has evolved these languages have gotten very very short-handed so if the warning the compiler gives you warnings it’s always interesting to read them and see what has changed but once we go back to the view controller where we created this entry view controller this let VC instantiate with identifiers what we can do is we can actually say VC update equals something this update is a function that we’ve created and every time we update every time we call this function in that view controller we want to reload this table view and actually we want to refresh the tasks that are saved so we’re gonna create a function called update tasks when we first load the app interview dead load we’re gonna call this to actually update our tasks and we’re also gonna call this once we call this update function from our entry view controller because we then want to reload this table view this is complaining that we need to add self in front of it because it explicitly tells this curly brace block that we want to call this function in this in this class the other thing we want to do which I won’t get too far into is actually put this function inside of a dispatch who doesn’t want to pop up a sink sorry main a sink and I don’t think I spelt it correctly sorry give me one second so this is this is those moments that I also won’t edit out where the actual naming people forget so what we’re gonna do is open Safari here we’re gonna quickly go to google and we’re gonna search with dispatch main and we get a bunch of links here let’s click on this first one so it’s very common that people forget these um these naming conventions which is totally cool yeah this is what we want so totally cool to look it up don’t ever feel like you’re the only one looking it up you saw myself in this video I’m looking it up but basically we want to do this it’s dispatch queue main async right so what this basically says is we want to make sure that we prioritize updating the actual tasks in other words calling this function that’s all this block means I can get into the nitty-gritty of it in terms of threading but I won’t for the sake this being a beginner video anyways moving along we want to come back to our entry view controller and wrap this up and we’re gonna wrap this up by calling this update function that we’ve added and actually this question work goes before this because this is an optional so we’re gonna say update question mark with the parentheses which is basically saying if this update function exists let’s call it and once we’ve called it let’s dismiss as view controller we’re gonna say navigation controller pop to root view controller animated yes so let’s go back to our view controller and let’s fill out this functions when we run it we can actually see our new tasks coming in here so we have this variable appear called tasks which is an array of strings what we want to do is first and foremost get our count in here and similar to how we did it in the entry of your controller we want to say it’s an int and we also want to make it a guard let because it could be an optional and for X rather we can do is let’s think for X in 0.2 count which basically says we want to create a for loop which is gonna iterate let’s see do we have an error yes we do have an error because we forgot a dot when we were basically saying is that we want to iterate through 0 up until this count inclusive of this count and the reason we want to do that is because we’re gonna get each of our tasks and add it to our task array and the way we do that is by saying a task equal user default value for key and the key you remember we added was tasks underscore in this case X because X is the current position we’re gonna start at and actually what we want to do because we start out as 0 would never actually use 0 because we add 1 to it every time we add we’re gonna say we can we’re gonna do X plus 1 and we’re gonna say well this is 0 up until this count because we’re adding 1 to it and once we have our task we’re gonna say actually garlotte to make sure it’s not empty let’s actually do an A flat so we’re saying if this this task that we’re trying to pull out isn’t empty we will be adding it to our tasks array and we want to make sure this task is a string when it comes back so we’re gonna add a a string up here which will get rid of this morning in just a second like so so we’ve gone over a lot so let’s run this and I will definitely do a recap at the very end so right now if we run this app let’s see we have our title period that’s empty table view let’s come here and type in a task so let’s do get milk let’s hit this button and when we come back we’re not seeing our actual task which is not good so let’s actually take care of why we’re not seeing her actual task the reason we’re not seeing your task is because we do refetch this we do recreate this task array but we actually forgot to do two things every time we go in try to recreate this task array before we update it you want to say tasks remove all which removes all the elements in this task array so we don’t show duplicates and we also want to reload our table view and we can do that by saying table view dot reload data so if we run this one more time we’ll see we have a gap milk here because the last time we did it we actually did save it to the actual device and the first time the app opens in this viewdidload runs we call this update and we fixed our implementation in here so we could actually get it now which is pretty awesome so let’s try another one let’s try to add clean office at this look at that we have clean office so this is a pretty simple to do a step and what we want to quickly add as the last piece of this app is being able to tap on one of these and to show another screen with a delete button so sim how we have this guard let to show the VC we’re gonna copy this code actually and we’re gonna create another function actually we can just do it in here so in the delegate function what I want you to do is copy that code and we’re gonna say let vc and we’re gonna use the identifier as task the view controller will be task new controller and if you recall we created this in the storyboard we’re gonna get rid of this update nonsense because that doesn’t exist on this view controller we’re gonna go to our task view controller and we’re gonna do a couple things we’re gonna create an iboutlet with for a label we’re gonna create a task which is a string optional we’re gonna say the labeled text equals task we’re gonna say that we want to have a function which is delete task we’re going to add a navigation item similar to the entry controller and a title we’re gonna give it a delete it’s gonna be done self and the selector is going to be delete the other thing we’re going to say in here is the stuff that needs to go into this function and basically what we’re gonna do and maybe I’ll leave it out specifically for the purposes of this video but because we have saved these tasks with numbers so every time we save it we incremented so task 1 2 3 etc and more or less infinite until we run out of space on our device which will probably get you into like the tens of trillions of tasks what we want to do is we can go into our user defaults and we can say basically set value and what we want to do is we want to set two values one value is the new count that when you’re going to create for count we want to decrement the count of tasks that we have because we’re removing one so for this well so probably step out right now and not fully finish because it’s a little out of scope we wouldn’t get the original account in just two minus one and what we also want to do is we want to actually set nil for the count of the current tasks so whatever the task current position is and the thing that is a big gotcha for a lot of people is when you’re removing a task so looking at this when you’re removing a task let’s say you have like 10 entries here and you remove one from the middle you need to shift all of the numbers for the tasks below it because when you go to list out these tasks in your table view you’re gonna have an empty number in the middle so if we have task 1 2 3 4 & 5 let’s add them actually really fast to exemplify this better if we have all these tasks when we delete this one because this is task 1 2 3 4 & 5 we’re left with 1 2 4 & 5 so what we want to do is all the tasks that are below 3 or above 3 quote-unquote we want to shift them down one position so it turns out to be 1 2 3 4 if we don’t do that we’re gonna have an empty entry so because you can imagine doing that it’s a little more involved I will omit it in this video if enough people put it in the comments or request it I can do a follow-up but I’m gonna comment this out for now and we’re gonna go to art of you or sorry our storyboard we’re gonna quickly add a label here and then we’re going to add some quick constraints to it and those are going to be twelve twelve twelve and twelve and we’re going to connect your outlet you can also connect it this way instead of actually dragging it to the label here and let’s run this and you’ll see once we click on a task we are taken to this view controller and in this label we don’t have our task and the reason we don’t have our task is in the view controller what we want to do is we want to say VC dot s equals tasks and the index path row so in the delegate function every time we click it we want to create this view controller and assign it a task so let’s try this one last time click on it and awesome we have our task show up right here and that’s all there is to it so on this view controller this is essentially where you can add a bunch of other functionality so you can have a function where the person can set a reminder a due date a notification sound notes about an event you can imagine a calendar app is built very similarly with a lot of calendar and dates calendar like functionality and dates involved so I’ll wrap this video up here it’s getting a little bit long let’s review really fast so we actually started off on the storyboard the storyboard has four things on it right now the first being in navigation controller in which this first list of view controller what I’m just calling it that’s not what it’s actually called technically speaking but this view controller the table view is we have this state we have this view controller which has our field to enter in new tasks we also have this view controller to show task entries we created two view controllers here but let’s start with just the basic view controller this one has a table view and eight array of strings we assign table view delegate and data source as well as a title we create this initial setup block to make sure that we start off with a count of zero we call this function every time we first start the app and as view controller to fetch rather not fetch but to update our tasks array from whatever we’ve saved that’s what this function is doing then down here we have this function which is called when we click on the add button at the top right of the screen it’s connected in the interface builder which is a storyboard which is why it has a prefix of IB action then we have the delegate function itself for the table view which is what happens when we select a cell we also have the datasource functions which supplies the number of rows which is a thing number of things and tasks as well as a cell in the entry view controller we have a field outlet we also have a function which is called also a closure called update which is void nothing returning void we come in here and set the delegate on the field we create a button for the person to tap done when they’re done entering we added a delegate function which is once the person hits return on the keyboard we’ll also add their tasks if there’s something in there by running that function that function we created it makes sure that we have text and it’s not empty it also makes sure that we have a count it increments the count it saves the new count as well as the task it calls the update function if it exists and it dismisses as view controller lastly we have the task controller and here I stubbed out this delete function to exemplify how this delete functionality would work we have a label outlet which we created we have this task variable which is a string optional which we assign our task content to before we push this controller on-screen in viewdidload we set the label as text to the task and we also create this button this delete button and attach it to this function which is all commented out because we didn’t actually implement it for the sake of time so yeah that’s a nice overview of a simple to-do list app it may not be as simple as some of you had hoped or thought but if you take a look at the code that we’ve written in here it’s very redundant there’s a lot of patterns you can identify and once you kind of wrap your head around some of these concepts like table views and navigation controllers it makes iOS development just open up to you and it gives you endless possibilities for combinations at different screens and actions and just things you could do so thank you so much for watching if you liked the video leave a like below subscribe if you’re new I regularly post iOS Swift development other tech videos welcome to the channel and I’ll see you in the next video