7 days of WordPress plugins, themes & templates - for free! Unlimited asset downloads! Start 7-Day Free Trial
FREELessons: 30Length: 4.8 hours

Next lesson playing in 5 seconds

  • Overview
  • Transcript

6.6 Demo: Todo

Now that you've learned all these new object-oriented language features, let's put them to use. In this demo application we're going to build a simple to-do list application that has the ability to create to-do items, save them, change their status, and view all open items. Let's get to work!

6.6 Demo: Todo

To wrap up our section on custom types including enums and classes and structs, let's go ahead and create a very simple application here. And this is going to be a very simple, somewhat cliche example these days of a todo application. So let's say I wanted to create some sort of application that I would be able to use to track some todos that I wanted to get done. So I'm going to actually use a couple different constructs here that we've been learning in this section to kind of drive this point home. As well as introduce a couple little new things here and there. So let's start off with the basic definition of what we're looking for. So we want to deal with obviously these to do items, and let's just say they have a name and a status, so we wanna specify a name, like I wanna do a todo item that's called make bed or something like that. And then I want it to have a status. It can have a couple different statuses, really anything you like, use your imagination. But let's just say three basic ones would probably get it done. We could have an open status, an in progress status, and maybe a closed or done status or something along those lines. And then we wanna be able to manage these todos. I wanna be able to manage several of them at one time and I wanna be able to open one and close another and check the status, maybe figure out which ones are still open to know which ones I need to work on. And so on and so forth. So that's the basic idea that we're tracking towards here. You can absolutely add tons more functionality. And I definitely urge you todo that, but we're just gonna start off with the basics, and then just let your imagination run wild. So I'm thinking of this in a couple of different ways. So I have a todo. I have this thing that maybe has a name and a status. And I'm starting to think status now status, so it's gonna have a couple different values, maybe open, in progress, and closed. And since we're talking about a type here possibly maybe an enumeration might suit that fairly well. So we'll start by creating an enumeration and we'll call this status. And we'll just define a couple different cases in here. We'll have an open status. We'll have an in-progress status. And we'll have a closed status and you can add in some intermediaries in there if you'd like but I think that should be enough to get us started. So now we have a status, we can talk about something having a status. Now that something is going to be a todo and the todo you could kind of go a couple different ways. So in my head I'm thinking this is going to contain a name, it's gonna have a name. And it's gonna have a status and so I wanna be able to refer to those two pieces of information. I'm not thinking right now that it's gonna have a lot of functionality in it. So I'm probably gonna keep it simple, maybe I'll just make it a struct. You could probably even go as far to say as you could create this as a tuple, because it's just gonna contain a couple pieces of data. But I think because I wanna mix things up a little bit here, I am gonna make this a struct. So it's just gonna be a very simple way to contain some data that I can refer to later on. And this will be a todo and we'll give it a couple different properties, we'll give this a name so it'll have a name which will be a string. And then we will also give this a status and as soon as we create a todo, well, we're just gonna give it a default status of open, so we'll say that's initially gonna to have a status of open. And then we also wanna be able to maybe give this a name as we create it. So we're gonna create that initialization function or method depending on what you wanna call it. And then we'll specify this as having a todo name, which will be a string. And then we'll come in here and we'll simply set name to be equal to todo name. Like that. So we'll go ahead and save that. So now we have this concept of a status. And we have this concept of a todo that has a name and a status which is defaulted to open. So now we really are to the point where the meat of this application is gonna come in, so I wanna be able to manage these todos. I wanna be able to have an array or a collection of todos. I wanna be able to add new todos to this, I wanna be able to start todos and stop todos, or close todos or set them in to in-progress, or things like that. And I wanna be able to do all of these things in a very simple manner, in a very centralized manner. So how can I do that? Well, I'm gonna start by creating a class and you can call this anything you like, but I think I'm going to call this my TodoManager. No superclasses for this but obviously based on the lesson that we did on classes and structures with a little bit of an introduction to creating these superclasses, you could go that route if you want, no judgment for me. So I think to this point all I'm really gonna need to do is manage and I'm gonna create this as an array. So I'm gonna manage an array of todos, just like this. And then we create this todo manager, I'm just gonna initialize this to an empty array. So I think that should be good to get us started. But now I wanna be able to, like I said, I wanna be able to add things to that. You could maybe remove some from that or maybe you could just leave them in there indefinitely. And just change the status back and forth to whatever it is you want. And then ultimately, I need a way to know which ones are still open. So I think that should be a good place to start. So let's go ahead and create an add method. So we'll say function add. And we'll go ahead an add a todo, so I will add a todo. Now there's a couple different ways to do this, and I'll show you both. So I'm gonna start by explicitly passing in a pre-created todo structure todo instance of my to do structure up here. Just to make it simple for this, all I have to do is say, todos and I can then, append to my array and I can append to do. So, that's pretty basic stuff, pretty simple there, that's not really a big deal. Now, one thing that Swift does allow you to do is to create functions with the same name, or overloaded functions. So I could create another one with add here, but this time I could specify a different input. So I could specify maybe a name here that's going to be a string. So I could specify a name for this todo. Now, obviously, name is not a todo, so I can't just add it on here. So what I would have to do is I would have to create an instance of a todo here so I could say var todo equal = todo. And then within here I'd have to initialize it so I would initialize it with the name of name. And then once I've done that, then I could go into my todos and go ahead and append it at that point so I can say todo here. Both ways will work and just to show you that I can add both of them in there. Just to show you that both ways will work and I'm gonna get a compiler warning here that's gonna say that I never really mutated or changed the value of todo. But so I can switch it to let, so you can see the compiler's gonna be pretty harsh on you. It's gonna let you know maybe when you should use a let or should use a var, but either way, it'll work just fine. So once again, you can use both ways to do it. To create this particular method, you could leave one out, put both of them in. It's completely up to you. They're both for convenience. So now I wanna be able to change the status. So I could go through, and I could create several different methods here to maybe start a todo, finish a todo all, open it todo, all those types of things. But what if I condensed those down a little bit and just kind of had them go through one particular method and maybe specify a status. So we'll go ahead and come in here and we'll say that we want to do specifyStatus. Or maybe changeStatus would be better, changeStatus. So once again, you can name these things anything you'd like at the end of the day, just as long as they make sense to what you're trying to accomplish and maybe anybody else that's reading your code. So I'm gonna go ahead and change the status here. So once again, I can do this a couple of different ways. I could pass in a todo or I could specify a name. So, in this particular instance, I'm just going to go the todo route where I'm gonna pass it in. And I'll go ahead and leave the opportunity for you to do these kind of overloaded functions, if you would like, but it's completely up to you. So I wanna be able to change a status and then I also want to be able to specify what that status is. So I need to be able to pass in a status also. So we'll just say status: Status like that. And I don't think we're gonna return anything. So I need to be able to find this particular to do because you never know, it might not actually be in here or not. And then once I find it, if I find it, I need to be able to specify the status. So what we'll do here is we'll go in and we're gonna need to try to find that todo to see if it exists so we'll say let. And one of the interesting little tricks with Swift 2.0 is that in an array these days. You can now specify an index of which takes in a predicate, which is just kind of a fancy term that's gonna talk about function types or closures, which we've learned about in a previous lesson as well. So I'll be able to come in here and specify a closure when all I really need to do, I wanna find the particular to do item within my array here that has a name. So I'll go ahead and say if zero.name is equal to todo.name, then that's the one that I wanna go ahead and grab. Now, the interesting thing here is this may or may not work because when we're looking for this particular to do in this array, it may not be there. So that's one of those situations where the index I was actually going to return an optional. So at this point, we might need to check for that. So we could go ahead and do an if let and kind of do all that kind of stuff but I'm gonna use the guard keyword in this situation. So I'm gonna actually say I want to guard on let index equal to todos and if I do that. Remember I need to specify an else and then some sort of block of code afterward to handle the situation and if it doesn't exist in this case. I'm just gonna say, sure whatever it worked, go ahead return out of here. So at this point now, because I've used guard, I now have access to this index, which is going to give me the index of wherever in that array lives the todo that I'm looking for. And then I can come down here and I can say, go into todos at index and I wanna set that status equal to the status that I passed in. So there you go. So that should take care of that piece of functionality being able to change the status. And now I wanna be able to show all of the open todos so I can maybe go yell at somebody to get it done or whatever have you. So we'll go ahead and create another function here or a method, and it'll say showOpen. And then I'm simply going to maybe put a little print here, just to give myself a little bit of space, so you'll be able to see it in the console. And then I'll do another little print here. And maybe we'll put some equal signs in here, and we'll say Open Todos. Just a little bit of formatting here, and then we'll print here. And then we'll just close this off so you can see when this block ends. And then we'll come up within here and then we're simply going to loop through the todos that we have so far and find the ones that are still open. Now another interesting trick that is kind of been included a little bit more, made more noticeable in Swift 2.0 is this concept of being able to do filtering, or additional filtering, in for loops, as well as the case statements that we showed earlier. So, what I can do now is I can say for todo in todo. So, I can loop through all these but instead of looping through all of them and having to check some sort of condition, within the for loop I can now at the tail end of my for in. I can specify a where clause which is pretty cool to be able to just automatically filter out a bunch of the garbage that I don't really necessarily wanna deal with. And only deal with certain instances so I can say for todo in todos where todo.status = Status.Open, so I only wanna find the ones that are open. So now, by the time I get in here, the every todo that I get in here, has a status equal to open and I don't have to check for it. So all I have to do at this point is print, maybe I'll just print out the name todo.name like that. So go ahead and save. So this is the basic functionality to be able to create a todo to add it to my todo manager and then manage the status of each one and then show all the ones that are open. So let's go ahead and check out an example of this. So the way that we're gonna do this, and we'll give ourselves a little bit of room here is I'll create a couple different instances of todo. So I'll say maybe bed will be equal to todo. And this one is going to be called Make Bed, like that. And then we'll maybe say var grocery is gonna be equal to todo and then we'll go ahead and set the name on this one to Go Grocery Shopping, like that. So now I've created these two todos, now I'm going to need an instance of my manager so go ahead and create a new instance of my TodoManager. Which doesn't take any inputs. So the first thing we'll do is we'll go ahead and do showOpen, so we can see all the different open, which at this point should be none cuz there shouldn't be anything within my todos array. But then let's go ahead and add these in, so I'll say manager.add, and remember I can do two different methods of add here so I'll just use the todo version cuz I've already got that taken care of. So go ahead and add bed. And then I will add grocery. And at this point now I should be able to do manager.showOpen again and I should be able to see two. And then we'll come in, and we'll change manager and then we'll go ahead and change status of we'll say bed. And will set that to Status. Set that the closed because that would be done at this point. And then at this point if I were to call showOpen again, manager.showOpen. Then I should get to the point where I would only see go grocery shopping cuz the make bed would have changed its status to something other than open, in this case, close. So let's go ahead around this and see how we did. So let's take a look so I originally create manager here. And then I call showOpen so I get open todos, there's nothing there. And then I go ahead and add bed and grocery, so then the next time I run and I get make bed and go grocery shopping. And then I change the status of making bed to being closed. And I go to showOpen again and sure enough, we're down to only that one todo. So there's a very simple example of how you can use classes instruction enumerations. All of the simple application all working together, working towards the same end goal. So once again, you could have created classes to do all of these things. Structures to do all of these things. Ultimately, it's going to be up to you, but like I said, when it comes to choosing between the two, 95% of the time, I'm gonna be choosing the class to do most of that. And if I'm just looking to store a couple pieces of data, then maybe I'll go with a struct, and then flip flop things back and forth depending on how I need them. So that's a very basic application that you could write all on your own using structs, classes and enumerations.

Back to the top