Transcript for:
CS50 iOS Track 2: Introduction to iOS App Development

TOMMY MACWILLIAM: Now that we've written some Swift, let's write our first iOS app. Before we do, let's walk through a few concepts that we'll need to understand in order to do so. When we're writing an iOS app, we're going to be mostly using a framework called UIKit. So UIKit is a library that the folks at Apple wrote and provided to us. And it has lots of different classes, and methods, and functions that we're going to use to create UI or user interface elements on the screen. So UIKit has different things like tables, and images, and buttons, and basically all of the different UI controls that you'd see in an iOS app, along with the ways to transition among different views, perform animations, all that stuff. When we're writing iOS apps, we're going to be following a pattern called MVC. And this stands for a Model View Controller. And this is a general software engineering pattern, but iOS uses it in particular. And what this pattern says is you want to separate out your models, which are how you model your data, so classes that represent just the data that you're going to display. And models don't say anything about how to display this data, or what this data looks like, or how this data interacts with something. All they do is say here is the data itself. The V in MVC stands for View. And you can think of the view as basically the opposite of your data. The view says here is some display of something, and it could be a bunch of different data that's passed into a view. But I'm just going to translate that into something that's actually displayed on the screen. Lastly, the C in MVC is Controller. iOS has this kind of funny convention where they call them view controllers. And so MVVC is perhaps more accurate, but you can think about the controller as the bridge between your model and your view. So the controller might say, I need to go fetch some data. I'll go fetch some data. I'll store that using my model, and then I want to pass that model to some view so the view can display that data. So it's kind of facilitating the interaction between the model and the view. So a lot of the code that we write is mostly going to be at the controller layer. We're going to write some simple models to represent data. And we'll write some simple views, but iOS has so many built-in views that we don't have to worry too much about that layer. So the first view that we're going to take a look at is kind of the bread and butter of iOS applications, which is the table view. So if you're using an app like the Contacts app, where you're looking at a list of contacts, that's what's called a table view. Even an app like Twitter, which is sort of a list of tweets, that's using a table view probably under the hood. A table view is basically just a list of anything, could be text, could be images. And this what's backing a lot of interactions in iOS. And so that's why we're going to take a look at this one first. When we open up our Xcode project, the first thing we're going to need to do is create some views. And Xcode has this cool feature called storyboards that are going to let us do that. So when I talk about storyboards, well, that is is basically a drag and drop container for all of your views. So in a storyboard, you can say the app starts on this view. It has these buttons. When you click a button, it transitions to this other view. And the storyboards are what we're going to use to build out the UI layer for our app. We'll also talk about outlets and actions. So this IB that's prefixed here, it stands for Interface Builder. But outlets and actions are basically a way for you to hook up controller methods or controller fields to your view. So from a storyboard, you might hook into an outlet in your controller that says, when I look at this button element, here's the code that it corresponds to. So that's something we'll see you in a bit. And then we'll also see segues. So a segue is a concept that allows you to map some action on a UI element, so maybe a tap on a row in our table view. When we want something to happen, so when we want to transition to some other view or transition to some other view controller, and we're going to use segues to do that. So that's another concept that we'll see shortly. So let's just jump right into it. So to get started, I'm going to open up Xcode. And then I'm going to click on Create a New Xcode project. Now this time, we want to make sure that we've selected iOS over on the top left, and then click on Single View App. Each of these other buttons will create a different template for you, so basically start you off with a different set of code. But we're just going to pick the simplest template here, which is the single view app, and then we'll click on Next. For our product name, this is where we're going to name our app. So in this video, we're going to be creating a Pokedex. So a Pokedex is an app that lists out all of the Pokemon that there are. And when you tap on each one, you'll see some more information about it. So for our product name, we're going to type in Pokedex. Next, for team, we're going to leave this at none. If you register with Apple, you can create a team and publish apps to the App Store. That's where you'd select whatever your Apple account is, but we're not worried about that right now. So we'll just leave that as none. For the organization name, here we're just going to put in CS50. Again, if you had an Apple account, you would put in your organization name here, but we don't have one. And, similarly, for organization identifier, we're just going to use this CS50 domain backwards, just that common convention. But, again, if you had an Apple account, here is where you would put that information. Next, for language, we want to make sure that we've selected Swift. So Swift is the modern programming language for creating apps. Objective-C is this older programming language that still works. But we're going to be using Swift throughout all of these videos, so make sure you've got that selected. And for user interface, make sure that you've selected storyboard. Storyboard is basically a way that you can create user interfaces by dragging and dropping various components. Swift UI is a brand new framework that Apple just came out with, and it's basically a different way of creating UIs. But we're going to go with storyboard. Lastly, you can leave all of these other things unchecked. So core data is a way for you to save data onto your device, and we'll take a look at how you might do that a bit later. And unit tests and UI tests are basically ways where you can automatically test out your app. So you can write test to make sure that your app is working as you'd expect it to, but we're not worried about that right now. So we're just going to leave those all unchecked as well. So now we can click on Next, and Xcode is going to ask us where we'd like to save the file. I'm just going to save this to my desktop. You can see there's a checkbox down here to create a Git repository. If you're familiar with Git, feel free to leave that checked. And if not, you can feel free to uncheck it. Doesn't really matter for the purposes of this video whether or not you've checked it or not. So we can just leave it checked, and then we can click on Create. OK, so now we can maximize Xcode and check out the files that it's created. And to recap, we have on the left-hand side here all of our different files. And so before Xcode just generated that one main.swift file, this time it's generated a whole lot more. So let's just start by walking through each of these to make sure we understand what we're doing. So the first file it generated is called the app delegate. And you can think about this as basically the main method for your app. So this is the class that's going to be used when your app is woken up from the background or started from the first time. It has a few methods in here that we're not really going to worry about right now, but let's just walk through them anyway. So the first thing we're doing is we're saying import UIKit. You may recall that UIKit is this framework and library that has all of these different methods and things we're going to be using. Don't worry too much about this UI application main. This is just saying that this is sort of this main method or the entry point for our app. And then we have a bunch of syntax that we should be familiar with already, but let's just sort of walk through it. So we're creating a new class. It's called AppDelegate. And this class is inheriting from a couple of things. So these might be parent classes. These might be protocols. But, basically, because they're following this colon, this is saying that we're using this UI responder thing that Apple provided to us and this UI application delegate thing that Apple provided to us. Our class has one field. It's called window. And the type of this window is an optional UIWindow. So as you're starting to see, many of the classes in UIKit are prefixed with this UI just sort of indicating that it's from UIKit and has something to do with the user interface. So this variable here, window, has a type of UI window, but it might be nil because we have this question mark. And it's also mutable, and it's not initialized to anything. And then we just have a few methods here that Xcode wrote out for us. None of the methods actually do anything, but just to take a look at the first one. So this method is called Application. It takes a few different arguments. The first one is UIApplication. And the second one is a dictionary that maps some launch options key to anything. In Swift if you don't know what the type of something is, you can just say any to sort of this generic object that could be anything. And you notice here this question mark means that it's optional. And all this method does is return true. You notice here that we're saying it returns a Boolean value. So Xcode also wrote out a kind of a bunch of nice comments here that explain what these other methods do. Again, you can feel free to read these comments, but they basically represent when your app is going through different states like going into the background, waking up in the background, being killed, stuff like that. And we're not going to need to do any of that for our app, so we're probably not going to open up this file again. The next file that Xcode generated for us is called viewcontroller.swift. Again, we're going to import UIKit to get all of those UI libraries. We're calling our class ViewController. And it's inheriting from this UIViewController class. So this class provides us with a bunch of base methods that we can override if we want to. And that's exactly what Xcode is doing for us here. So we have this first method called viewDidLoad. And we've overridden it. Though we haven't done anything with that, but we can if we want to. So this viewDidLoad method is going to be called automatically by iOS when this view loads. So we're saying this ViewController was created for the first time, and you can use this to do some setup or initialization, which we'll look at later. But for now, all we're going to do is call this viewDidLoad on the superclass. So maybe inside of UIViewController, there's some logic inside of viewDidLoad. It's good practice just to call super.viewDidLoad in case there's anything in there that's really important that we don't want to miss. So you'll see this as another convention just making sure to call the superclasses method inside of any method we override. And to do that, we just use this super keyword. OK, so, next, we can open up our storyboard. So now we finally see an iPhone on the screen, but it doesn't have anything yet. But this is where we're going to start adding different elements and buttons to our storyboard. If I come over here to the left-hand side and expand this View Controller scene, that's where going to start seeing the elements that we add. So we'll come back to this. Just to quickly walk through the other files Xcode generated, the first is this assets file. If you're adding images or something like that to your application, you can put them inside of this asset package. Next is another storyboard representing the launch screen. So if you've opened up an app, which you probably have, for the first time, you can show sort of that initial loading screen before everything is loaded. A lot of apps have some simple animation or something like that. This is where you'd put it is inside of the launch screen. So your launch screen isn't really interactive. It's usually just a picture, or a color, or just something to display on the iPhone while the app is loading up in the background. And, lastly, we have this info.plist file. And you can think of this as basically a configuration file. Again, Xcode has basically generated everything we need to worry about already. So we're not going to modify this. But, for example, it's saying that this launch screen storyboard file, that's the file we should use for our splash screen. And the first storyboard that we should open up when the app opens up is that main.storyboard. So that's sort of how that mapping is happening inside of your application. But, again, we're not too worried about this info.plist file right now. So let's start writing our app. So, oftentimes, I'd like to start by writing the view and just sort of putting some things on a storyboard to make sure I understand what type of code I'm going to need to write. So we're going to start off by starting over. So we're just going to delete this initial view controller. And, instead, we're going to want to add a special view controller called a Table View Controller. So up in the top right, you'll see this little Home button. And when I click that, I get this nice little autocomplete area where I can add objects to my storyboard. So the object that I'd like to add is a Table View Controller. And a Table View Controller is basically this nice utility class that's going to display a table view for me and have all of the different methods that I need to create that table view. So if I just start typing table view, I'll see it here. Then I'm just going to click and drag onto my storyboard, and there we go. So I have now a table view inside of my storyboard. So let's go back to my ViewController class. I know that this is going to be a UI Table View Controller. So rather than inheriting from a regular plane UI view controller, let's change this to be a UITableViewController. So now I have this source file. I have this thing in my storyboard, and I want to connect the two. I basically want to say that this thing in my storyboard should correspond to this source file. So to do that, I'm going to come back over to my storyboard. I'm going to make sure that I've selected Table View Controller. And then I'm going to come over here to the right-hand side. And I'm going to click this icon here. And the first thing here-- this is called the identity inspector by the way. This first element on the right- hand side here says Class. You notice that right now it's just sort of this placeholder because we haven't really mapped this thing in our storyboard to any of the classes that we've written. So if I click on this dropdown, you see I'm just going to get this one option. That's ViewController. So if I click that, then now we've said that this item in the storyboard corresponds to this ViewController class. And that's really important or else Xcode is going to have no way of mapping this UI to our controller. So one other thing that we have to do is come over to this fourth tab here, which is the Attributes Inspector. And I'm going to scroll down a bit, and I'm going to see this checkmark here that says Is Initial View Controller. So before I deleted that other view controller, this was actually checked. So I'm going to need to check it here. And this basically just tells our application and Xcode that this is the part of the storyboard that we should open up first. Right now it's sort of the only thing, but we're going to add more later. And so we do need to tell Xcode that this is the thing that you should open when you first open up the app. OK, so if you come back over here and click on Run, I'm going to see my iOS simulator. And here is my table view. You'll see here that it's completely empty because we haven't added anything to the cells yet, but it's a start. We finally put something on the screen. So now let's add some data to our table view. To start, let's just declare an array that contains a few Pokemon. I'm not going to write out all 151 right now. But let's just get started by writing out a simple list and then displaying everything in that list. So the first thing I want to do is to create a new class representing a single pokemon. So this is basically the model for our app because it's going to contain the data we want to display. So let's just create a new Swift file. It's just going to have that one thin in it. So to come over here to the left-hand side, click on this Pokedex folder. And then Control-Click, and you'll see New File. So I'm going to click on that. And I'll get this kind of familiar looking screen again. So this time I just want to create a Swift file. And I'm going to click on Next. It's going to ask me what I want to call that file. Let's call it Pokemon. And let's click Create. So there we go. Everything is blank save for this sort of header comment. And so in this simple version, let's just say that each pokemon just has a name and a number, super, super simple. So let's create a struct. Let's call it Pokemon. And it's got two fields. It has a name. That's a string, and it's got a number. And that's an integer. So that's it. So this is basically the model for application. It's really, really simple, just a struct with the two fields. Now that we have that model, let's use it. So I'm going to create a new field on this class that's just a list of Pokemon. So to do that, we're going to start with left. We're going to say Pokemon. We don't need to worry about the type because the compiler is going to figure that out. And then inside of this list, we're going to use this class that we just created. So here's my Pokemon. And you'll notice here that when I hit open paren, I had this nice autocomplete complete with the constructor already. Something that's nice about structs in Swift is that the compiler is automatically going to generate a constructor with all of the required fields. So I have those two let fields, and so Swift generated this constructor for me. Well, let's get to the first three. So Bulbasaur is 1. Ivysaur is 2. And Venusaur is 3. OK, pretty simple. Now we've just said that there are three Pokemon here. We're my new class. So now let's use this data. We don't need to worry about viewDidLoad, so we can just delete that. But UITableViewController has a few different methods that if we override them are going to enable us to display things in the table view controller. So the first method that we need to override is called numberOfSections. So if I just start typing number of sections, you've got this nice autocomplete. If I just hit Enter, I've got all this stuff done for me. So this method is called numberOfSections. Any table view in iOS can have sections. And within a section, it can have rows. For instance, in your contacts app, there's sort of a section that says A, and there's a list of people that start with A. And there's a B, list of people who start with B. So our app is just going to be a flat list. So we can just return 1. Say that we've got one section. That's it. Next, we want to specify how many rows are in each section. So if I just start typing number of rows, Xcode autocomplete saves me again. I'll get rid of this right-hand side thing so it fits. And now we have this other method. And so now when we think about how many rows do you want to have in our tableView, well, you want to have one row for each element in our model. So we're just going to return pokemon with a lowercase p dot count. And this is just a simple property on any list that says how many elements are in it. We saw that in our last example as well. So now in this runs, we should have three rows. So the last thing we need to do is to display the data in the row. So to do that, there's a method we need to override called cellForRowAt indexPath. I'm going to hit Enter again, generate a bunch of stuff for me. And now this is where we're actually going to connect this data to our view. So you'll notice here that this method returns a UITableViewCell. So, eventually, we're going to need to return one of those. But before we do, let's take a look at our storyboard again and just set some properties on this row. So if I come over to the storyboard, I'm going to click on where it says Table View Cell. I can either click it here or here. It's the same thing. I'm going to open up this right hand side. And I'm going to have to specify a few things. So I'm over here in the tab, which is the Attributes Inspector. And the first thing I'm going to change is the style. So you can specify a custom table view cell. You can add different views to it if you want. Our cells are pretty simple so we don't need to do that. So I'm just going to set the style to basic. So once I do that, you'll see that the storyboard changed. And now I have this text field inside of the cell. And this is just because basic is sort of a built-in cell style that can just display one line of text, but that's all we need to do. So let's click on this again. Next, we're going to fill in an identifier. So an identifier is basically a string that distinguishes among different types of cells. So in our application, we just have one table view, and all of the cells are the same. So they're all going to have the same identifier. But you'd imagine if you had an app with two or three different table views and each table view had different types of cells, you'd need to specify different identifiers to distinguish them. So let's just call our identifier-- let's just call it a PokemonCell because that's what it is. Nothing is going to change in a storyboard when we do that. And the last thing I want to do is add an accessory to the cell. So if I come over here to Accessory, instead of none, I want to click on Disclosure Indicator. And what that did is that just added a little arrow on the right-hand side of my cell, which is nice. And this is a little UI element that indicates to the person using the app that if you tap on this row, you're going to go to some other thing to display more information. So that was kind of nice. We don't have to worry about drawing an arrow or adding it for us. We can just use the built-in there. There's a bunch of other properties here that you might want to play around with like background or tint. You could sort of change things like the size of cells. But this is it for now. We just want to display text in each of our cells. So we're not going to do too much. So now if we were to run the app again, it would still be blank because we're not using any data. So let's not do that and, instead, write our last method. So you'll see here that Xcode is already being helpful. It's either helpful or annoying depending on how you're feeling the day. It's saying that we need to return a UITableViewCell. So let's do that. So we want to create a new variable. We'll call it cell. And we want to get something that represents the current row. And so rather than constructing a cell each time, what we want to do is instead use this pool of cells that our app already has in memory. If we created a cell every single time we needed one, our app would start using a whole lot of memory. And often, we're not looking at too many cells on the screen at once. If our table view is over 150 items, not all 150 are going to fit on the screen at once. And so it doesn't make sense to allocate all 150 cells upfront if we're only displaying 10 of them or so. And so iOS this built-in mechanism to do this for us. So there's going to be some automatically created pool of cells. And what we're going to do is we're going to say, I need a new cell. Just pull out of that cell-- pull out of that pool a new cell. Set some properties of that that I want to display, and then return it. So to access this pool is actually really easy. The first argument to this function is called tableView. So I'm just going to say tableView dot. Again, I've got this whole long list now. And I know that this method is called-- it starts with dequeue. So I'm just going to start typing the word dequeue. And I want this second one here, dequeueReusableCell withIdentifier for IndexPath. So we'll go what all that means, but let's just hit Enter. So the first argument to this method is our identifier. And remember this is what we needed to distinguish cells from each other. So this is where the identifier comes into play. If this table view had multiple different cell types, this is where you can specify I want a cell of this identifier type. So we've only got one, so that's easy. And we called it pokemon cell. So that's the first argument. The second argument to this function is our index path. So an index path is basically a pair of integers for one representing the section the cell is in and the second representing the row the section is in. So here we don't care about section because we just said that there's one section in the whole table. So we're not going to worry about that. We just care about the row. And so by specifying the row into this dequeue cell method, we're basically making sure that iOS doesn't reuse a cell that's already on the screen. Now you'd imagine that if we're trying to display row 1 and it pulls from this pool of cells, the cell that's currently being displayed at row 2, that's going to be really bad because we're going to blow away row 2's contents. And so that doesn't make sense. Luckily, we don't need to worry about any of this. iOS takes care of all of this for us. We just have to specify the IndexPath that our cell is at. And so how do we know that? Well, it's simple. It's just passed into this function. We have this IndexPath parameter. So if I just say IndexPath here, I'm done. So what I've just done is I've said let's take a cell from this pool, and iOS manages allocating everything for us, creates the cells, and destroys them as I need them. All I'm saying is just give me a cell and I don't have to worry at all about where that cell came from. And so this is really nice. So now that I have the cell, ultimately, I want to return it. And that's going to make this little compiler warning go away when I click Command-B. And sure enough, it's gone. But just grabbing a cell and then returning it without doing anything isn't all that useful. And so what I want to do is change the text of the cell to be the name of the Pokemon for that row. So I'm going to say cell.textLabel. Again, autocomplete is going to help me here. I didn't actually remember what it was. I remember it started with text. I just started typing text and there we go. And then there's a property on textLabel called text. And then I'm just going to set that equal to my model. So here's my list of pokemon. I'm going to index into this array based on my current row. So my current row-- again, I'm going to use that indexPath variable, but this is struct that contains a bunch of stuff. And we want to just grab the row element. So this row is always going to be between 0 and 2 because we know that there's only three elements here, and we've specified that by saying pokemon.count. But this is an object, and so we just want to display the name. So name is a string, and now our types make sense. And so there we go. We now have said with this cell that you just gave, let's grab its textLabel, set its text to be the name of our Pokemon, and then return that cell. You notice here that as I was using autocomplete, Xcode added this little question mark for me. And the reason being is that inside of a UITableViewCell, this textLabel is actually optional because in some cell types, it's not called a textLabel, it's called something else. And so it could be nil. And so what this syntax does is says if this variable is nil, just ignore this line. I just as easily could have done if let, or guard let, or even put an exclamation point here. But this is just another sort of piece of Swift syntax that's kind of nice. It just says, if this is nil, don't crash. Just move on to the next line and carry on with your life. So that's everything. Just to recap, we've specified three things. We've said how many sections does this table view have? How many rows are in each of those sections, just the size of our list? And then what do we do with each cell we want to display? Here we just grab a cell, change its text, and then return the cell. So now let's run this. So let's come up here and click the Play button. Our build succeeded, and there we go. We've got a list of three Pokemon. We've got these nice arrows indicating if you tap them something should happen. We haven't done any of that yet, so tapping it is just going to highlight it. But there is one thing missing from this view that you've probably seen in a lot of iOS apps, which is a title bar. If I were using an app and I needed to go back, you usually a title bar at the back button, or other controls, or a title. So let's add that to our app. So let's come back to our main storyboard and come back to our Table View Controller. So that title component in iOS is called a Navigation Controller, which makes sense. The Navigation Controller is basically this container that's going to enable you to navigate among different view controllers. So if I click on View Controller and then come up here to the Editor menu, if I scroll down a bit, you're going to see Embed In. And then I've got a few options here that's kind of cool. And so if I just click Embed In Navigation Controller and click, here's what just happened. So Xcode created a new navigation controller for me. And it put inside of it that table view that I just added. Something else that it did kind of nicely is that if I open up this right-hand side and I click on Navigation Controller, you'll see that it actually changed my initial view controller. It's saying that this navigation controller, the sort of container over my views, that's where my navigation should start. And now I have this title bar. This wasn't here before. If I double-click or if I just click on this here and come over to the Attributes Inspector on the right, this is called my Navigation Item. So Navigation Item contains a title. It has some text at the back button, has some other stuff. But all we want to do is give it a title. We'll just say Pokedex. And, now, if I come over back to my storyboard, I've got this nice title that wasn't there before. If I click Run, now my app has a title and looks a bit more like what iOS table views typically look like. We have a navigation item up on top with the title that we've specified and our table view. So now that we have our table view working, we can see a screen where we have a list of those Pokemon that we hardcoded. Next, let's look at how we can create a second view controller to display more information about each individual Pokemon. So to do that, let's start by jumping back to my storyboard. So I want to add another view controller to this storyboard. So I'm going to come up here in the top right again, and I'm going to start searching for a view controller. So this view won't be a table view. This will just be a plain view controller, and we're going to add a few of our own views to it. So I'm going to drag this view controller over here. And now we can see I have a second screen on my storyboard. So this view will just have a few text fields to display information about the Pokemon. So let's come up to the top right and add what's called a UI label. And this is pretty simple. It's just a view that can display a string. So I'm going to drag this label onto my second view controller. You can see these nice little alignment lines will show me when it's centered. So let's open up this panel to the right. Now let's change a few things about this label. First, that font is kind of small, so let me bump that up a bit let's say to 24. That looks pretty good. Let's make sure it's going to have enough space for any Pokemon name, which might be long, so I'm just going to drag this to the left and right. And you can see those alignment lines again telling me when I'm centered. Lastly, let's come over here to text alignment and just center this. So something else I like to do with these views is to add in place holder data while I'm designing the storyboard just so I can get a better sense of what the view is actually going to look like. So I know that one of the Pokemon's name is Bulbasaur, so I'll just try adding that. Underneath this, let's have another UI label that's going to show the number for each Pokemon. So once again, I'll come up here to the top right, drag in another label. And let's make this font a little bit bigger. And let's do the same thing. Let's increase the width of this label a bit. Let's center the text. And then I want it to look like a pound sign followed by a couple of zeros and then the number. So this is what our second view is going to look like when all is said and done. After I've created something in the storyboard. Now let's create a new Swift file that can be the source for this view controller. So I'm going to come back over here to the left, control-click on that Pokedex folder, and click New File. So now I'm just going to create a new Swift file, and we'll call this my PokemonViewController. OK, so I have my new Swift file. So let's define a new view controller class. So the first thing I want to do is make sure I'm importing everything from UIKit since that's where all of the UI elements are defined. And I'm going to say class PokemonViewController. And this time I'm going to inherit from UIViewController. Last time, remember, we inherited from UITableViewController because we had a table view. This time we don't, so we're just going to inherit from this plain UIViewController class. So the first thing I want to do is create what's called an IBOutlet. And this is a way for me to connect those labels I just added to my view controller into my Swift source so that then I can manipulate them from somewhere inside of this view controller. So to do that, I'm going to create two fields in this class. I'm going to say @IBOutlet. We'll have it be mutable, so we'll say var. And we'll call this first one a nameLabel. And I'm just going to add an exclamation point at-- I'm sorry. nameLabel, UILabel, and then I'm just going to add an exclamation point here so we don't have to worry about whether or not this is nil. And then I'll add one more for the number. So we'll call that numberLabel. And, again, we'll say UILabel here with an exclamation mark at the end so we don't have to worry about whether or not this is nil. And so you'll see here that Xcode has these two little circles over here on the left indicating that I can actually take these labels and connect them to somewhere in my view controller. So let's go ahead and do that. We'll open back up the storyboard. And just as we did last time, let's first set the class of this view controller. So I'm going to select the View Controller on the left. Come over here to the right-hand side, jump into the Identity Inspector. And under class, I'm going to select my new PokemonViewController. So now my storyboard knows that this view controller corresponds to that custom class that I just created. Now to connect those two fields we just created to the storyboard, we're going to come over here on the left. We're going to hold down control, and we're going to drag from PokemonViewController over here. And you'll notice that my first UILabel is now highlighted. So when I let go, you can see I have this little menu showing me the outlets that I might want to connect. So I created that nameLabel outlet before so I'm going to click on that. So now that name label is connected, and let's connect our other label by control-click and drag and selecting numberLabel. So now every time I reference that name or numberLabel inside of that Swift file, I'm going to be able to manipulate this view that I just added to my storyboard. To double check that everything is correct and hooked up right, let's just select this first label. And on the right-hand side, come all the way over to the last one here, which is the Connections Inspector. Let's click on that, and you can see I now have a referencing outlet. We're saying that this nameLabel is inside of the PokemonViewController, and everything is hooked up the way we'd expect. If I wanted to get rid of this, I could just click on this little X, and it would disconnect the outlet. So now let's jump back to our second view controller. So what we want to do is somehow get some information from that first view controller and display it here in the second one. So let's create a property for some Pokemon object to display. So we'll say var pokemon. This time we don't say IBOutlet because this doesn't correspond to a view in the view controller. Then the type is going to be that Pokemon class we created before. So when our first view controller creates the second view controller and transitions to it, we're going to pass in this Pokemon information. So for now, let's just assume that we have it already, and let's use it to change what our view looks like. To do that, we're going to use that viewDidLoad method. Remember that this is a method that's automatically called by iOS when your view controller has just finished loading. So this is a perfect method to use because each time the view controller loads, we want to change that text or that label to be equal to whatever the Pokemon that we passed in. So we're going to say override func viewDidLoad. Let autocomplete do that for us. Remember we're going to call super here. In case that viewDidLoad method inside of UIViewController is doing something important, we're just going to call super to make sure that that still happens. And so now we can just set the value of these two labels. So I can say nameLabel.text. That's just a property on that UILabel. And we'll set the name equal to our Pokemon's name. That's easy. Now let's try the number label. We'll say numberLabel.text equals pokemon.number. So let's try building this and make sure that we don't have any problems. OK, so we do. So let's see what this error says. It says cannot assign value type Int to type String. OK, that makes sense. If you remember that Pokemon struct, we had number as an integer field. But text requires us to use a string. So all we have to do is convert an integer to a string. In Swift, that's really easy. I can just say String, and that's just going to wrap that integer in a string so we can actually display it. So this is basically the second half of this interaction. Once we have a Pokemon and this view controller is displayed, then we're going to display the information we need. So now let's write the first half of this interaction, which is how we're passing data from that first view controller to the second. To do that, let's first jump back to our storyboard. So you'll see that there's nothing connecting these two views. So there's really no way for me to get from this first view controller to this second view controller. To do that, we're going to create what's called a segue. So a segue is just a way of defining transitions between view controllers. So to create a segue, I'm going to come over here to my cell on my first view controller. Again, I'm going to hold down Control, and I'm going to drag over to this second view controller. You'll notice again that it's highlighted. And when I let go, I get this menu saying there's a bunch of different segues I can create. So I'm going to pick the first, Selection Segue. This is just the simplest one. It's just going to show that view controller. So I'll tap show. And now in my storyboard, you'll see I have a segue defined between these two view controllers. So let's click on that segue. And just as we did with our cells, let's give this segue a unique identifier. So we'll jump over here to the Attributes Inspector. And, again, we have this identifier, so let's call it our PokemonSegue. So now we're going to use that string inside of our first view controller. So let's jump back there. And to use the segue, we're going to override another method that's defined on every UIViewController called prepare for segue. So I'll just start typing that and let autocomplete fill in all of the details for me. So now let's think about what we want this method to do. The first thing we want to do is make sure we know what segue we're using. You can imagine in any view controller you might have two or three different segues to different view controllers depending on what button was pressed. In this case, we only have one, but we're still going to use that identifier to make sure that we're looking at the right thing. Then we want to get a reference to this new second view controller and pass some data to it. So, first, let's use this segue object that's passed in. It looks like the type is a UI storyboard segue. And on that object there's a property called identifier. So remember we called our identifier our PokemonSegue. So let's just make sure that we're always using that. Next, we want to get the destination view controller that we're moving to. Luckily, segue has a property called destination. But you'll notice from this autocomplete that the type of destination is a regular UIViewController. And that makes sense because you're going to be moving among UIViewControllers. But we want to make sure that we're accessing this as a PokemonViewController. The reason being is we defined that field called Pokemon, and we need to use that field to pass in data. But not every UIViewController has a field called Pokemon. So what we need to do is cast this destination UIViewController into an instance of a PokemonViewController. And so we're going to use some Swift syntax to do that. It's very similar to that optional syntax we saw before. We're going to say if left destination equals segue.destination as followed by a question mark and then the name of our class, which is a PokemonViewController. So here this is really similar to that optional syntax. This is going to say if this segue.destination, if it can't be cast to a PokemonViewController, if it's of another type, then this is just going to return nil, and we're never going to enter this block. But if it can be cast and we expect that it can because we know what type we put in the storyboard, then now this destination variable is of type PokemonViewController. And that's great because now we can say destination.pokemon. And now we can pass along whatever pokemon corresponds to the row the user just selected. So to get that row, there's a property on table view called selected index path for row. So let's use that. We're going to index into our Pokemon array using tableView.indexPathForSelectedRow. And you'll notice that this isn't an optional, so let's just put an exclamation point here because we know that some row must be selected in order for us to be in this segue method. And, again, remember this index path has both a row and a section, but we only care about the row. So we're just going to say dot row. OK, so what we've done here is we've indexed into that list, getting the item that corresponds to the row the user just selected. And now we're passing that to our new view controller. You'll notice that we didn't have to instantiate that view controller ourselves. There was no creating that object. That's something that iOS does for us, and all we need to do is manipulate the segue to change the data that's used in that view controller. So let's try running this app and see what happens. OK just like before, I have my list of Pokemon. Last time when I tapped them nothing happened, but let's try doing that now. OK, so it looks like we've just pushed our second view controller onto the stack, and we've passed along the information we were trying to pass along. If I tap Venusaur instead, you'll notice that this data is being transferred back and forth between these view controllers. But there's one last thing that's wrong. Remember in my story board I wanted to format this number with a hash sign followed by leading zeros to make sure I always had a three-digit number. So let's look at how we might want to do that. Let's jump back to our PokemonViewController. And rather than just wrapping this Int in a String and just taking that number straight away, let's use a method on the string class called format. And format is going to be exactly the same as printf that we saw earlier. We're going to define some format string. And then we can pass arguments to format so that we can insert those values into the string. So we're going to say String format, and the first argument here is going to be our format String. So let's start with a hash. And then remember in printf If I want to pad a number with leading zeros, I can say %03 if I want this to be a total of three digits followed by d because I'm passing it an integer. And then, finally, let's just pass in that Pokemon number. So now let's run our app again. Let's tap on Venusaur. And now this is what we wanted our data to look like. Let's tap on one more just to be sure, and everything looks like it's working. So now we have two view controllers. They're able to pass data back and forth to each other so that we can display more details about something in our table view. Now, in our next video, we'll take a look at how to load this data dynamically from somewhere on the internet rather than just hard coding this list.