This workshop will be retired on May 31, 2020.
Debugging in Xcode: Part 120:38 with Gabe Nadel
Xcode has a whole host of debugging features; let's explore those you'll be using most often. Once we have a lay of the land, we can start hunting down some defects in our code.
All right in the last video we learned what a breakpoint is, why you'll be using 0:00 your debugging skills even when things aren't broken, and we even introduced you 0:04 to Grace Hopper's famous moth, but enough with the chitchat let's get our code on. 0:08 So here we are comfy and cozy in Xcode, but as familiar as we've gotten so 0:12 far there are probably more than a few buttons you haven't clicked yet. 0:16 Not to worry it's a big powerful program and 0:20 we're going to explain some really important functionality is in this video. 0:22 I'll give a very quick overview of the UI Layout as it relates to debugging but 0:26 I won't go into depth on everything we'll do that once we start hunting for 0:29 bugs in a minute or two. 0:33 So here we have an app called TableSearch, it's a sample app you can download from 0:35 Apple's developer site and I've linked that below. 0:39 I've made a couple small additions for our purposes, but it's 95% as it was when I 0:42 downloaded it, and I have my version linked below as well. 0:46 If you wanna follow along, be sure to use my version. 0:50 Now we'll be using this app as our victim du jour, but everything we 0:53 talk about is applicable to whatever code you decide to debug in Xcode. 0:57 Now, I'm gonna run this on the iPhone 6 sim. 1:01 But I'm gonna zoom out so it fits on my screen better, there we go. 1:07 By the way you can quickly resize any sim by using command one, two, 1:11 three, four or five or just heading up here to the scale menu where 1:16 you can pick the zoom amount 50% actually 33% looks good here. 1:20 We'll begin poking around the code in a second, but first let's get the lay of 1:25 the land in terms of debugging and so I'll hide the sim over here. 1:29 In the left pane over here we have the debug Navigator. 1:32 Up here we have our debug gauges our app is running so 1:35 we're showing some memory usage here. 1:39 On the next tab, we have the break point navigator. 1:41 Nothing much to show here cuz we haven't seen any break points yet. 1:45 Down here in the center bottom pane, which we can hide and 1:48 show using this button over here, we have the debug area. 1:52 This area can either be set to the variables panel, 1:57 that's this one over here, or you can set it to show the console. 2:00 If you want to show both that once you can do that as well. 2:05 You'll find that as you test, you'll often want both of these to be available. 2:07 So if it doesn't automatically happen when you run your app, 2:12 you can head up to Xcode, Preferences and then when it says running starts 2:16 you're gonna wanna check show debugger with variables and consoles, and 2:20 then you might want to do that at builds too if it's not in there. 2:25 There you go, now right here above the debug pane is the debug bar. 2:34 From left to right the buttons hide and show the debug area, 2:42 toggle breakpoints on and off, pause or start execution, 2:47 step over, step in, step out, this one right here will help 2:52 you debug your view hierarchy, and this will simulate a location. 2:57 Here you can choose your stack frame which will eventually have breadcrumbs here that 3:03 show your files and your method names and again, 3:07 don't worry we're gonna go over these in more depth. 3:10 Let's return to our app, 3:13 I'm actually gonna zoom in a bit more here, there we go. 3:14 So here we see a list of many of the famous Apple products we know and 3:20 love along with their initial launch year and their price. 3:23 Now this app is just meant to demonstrate table views, and 3:27 the search bar that's up here. 3:30 But if we tap a cell, we see we get taken to a very bare bones detail page, 3:33 you can see the details listed again, and then we have a button here to purchase 3:37 the button doesn't actually do anything by the way. 3:41 Also don't worry if you aren't yet familiar with table views, 3:45 you will be soon enough and for our discussion all you have to know is that 3:49 this back here is the main table view and this would be a detail view. 3:53 Now I click into iPhone and it looks okay, but 3:58 when I click iPod I noticed the price is missing, hm, what gives? 4:02 When I go back to the main table we see that we do have a price here but 4:07 it's not in the Detail View that's weird. 4:12 Clearly the app has a price for 4:15 the iPod it's just not showing up in the Detail Screen. 4:17 Now we could go hunting for the bug right now, but since we only have nine items in 4:20 our list, let's just check them all maybe that will give us a clue. 4:24 Okay, just to be sure iPhones got its price, iPods missing, 4:28 okay, okay, okay, iMac is missing too, 4:34 I'm gonna jot this down on a Notepad we're missing iPod and iMac. 4:38 Okay, so just those two are missing. 4:50 In a way we've now created our reproduction steps. 4:53 We can run the app and tap on either iMac or iPod and that produces our buck. 4:56 Now this app is pretty small, so we could just poke around and 5:01 try to solve the issue, but that wouldn't teach us much. 5:04 Let's use some debugging techniques to learn a little bit about how the code is 5:06 structured and maybe that will uncover our bug. 5:10 We can stop the app from running and next take a look at our files. 5:14 We have a main table here, we've got a detail table, a product which is 5:18 probably the class, yap it is used to represent our products and we have 5:23 an app delegate which we know is the entry point to our app let's start here okay. 5:28 Inside the app delegate, we see that the first thing we do inside our did 5:34 finish launching with options method Is create an array called products and 5:38 the elements of that array seem to be, well product objects. 5:43 If we right click on the products, we can jump to the definition. 5:48 And lo and behold we're inside our product file which is where we define the class, 5:54 product. 5:59 Okay we have some enums for let's see the hardware name we've got some constants 5:59 to hold the product titles, hardware type, year introduced intro 6:06 price okay this last one probably has something to do with our issue. 6:11 We can scroll down and keep looking and 6:17 it doesn't look like the rest of this will be relevant just yet. 6:20 If we go back,we see that we're at our products array and 6:25 we're setting all the values we were displaying on the main table. 6:29 Let's drop in a few break points, one up here at the top of the method where we 6:34 shouldn't have any products in our ray, one after iPod, so 6:37 iPod's here, and then one down here at the bottom. 6:42 By the way, you can add these breakpoints just by clicking you can slide them up and 6:48 down, you can deactivate them, or disable them by clicking and 6:54 you can make them vaporize in a big puff like that. 6:58 You can also edit a Breakpoint, you can right click that and 7:02 click Edit Breakpoint, but we're not gonna go into all of this right now, 7:05 however there is some good information on that linked below. 7:10 Okay, when we run our app we see this sim it appears to hang here, 7:16 why is that happening? 7:21 Well it's because we've stopped at this first breakpoint we put in here. 7:24 So we haven't even completed our DID finish launching the sim isn't broken 7:29 nothing's wrong at all we just paused very early in the execution. 7:33 So we can see over here we've got a list of variables in our variable view. 7:37 I don't see products listed anywhere at all here. 7:43 Let's try running to our next breakpoint. 7:48 No, it's still not here let's step in and see what happens. 7:53 We're taken in here to where we're gonna set the device type of title variable. 7:59 Let's step in again, we're seemingly back where we were, 8:05 though we're actually a little further along, you see where we're just in 8:08 the device type title which is we see the first part of the initializer here. 8:13 If we step in again, Then we're actually to the hardware string. 8:18 Which we can see is further along here. 8:27 If we step in yet again where do we think we'll end up? 8:32 That's right, where we actually set the hardware type. 8:37 Now rather than do this so slowly we know we have a breakpoint waiting for 8:40 us later so let's just hit play and we'll stop at that next breakpoint. 8:44 Okay, here we are. 8:48 Now let's take a pic at our products, we see we have nine values. 8:50 See how I moused over here that will display our nine products and 8:57 we can open them up we have some very familiar information here. 9:01 It's also worth mentioning t hat while we had our breakpoint set here already and 9:05 hit run, you can always add new breakpoints and 9:10 move them around when your code is paused. 9:13 In fact, very often, you may only set a breakpoint or two when you actually 9:15 hit run and then once you start poking around you start adding a whole lot more. 9:19 We'll get rid of those now. 9:24 Now we already have our products are right,so we could do a little more 9:26 troubleshooting, but this block right here is a good way to demonstrate 9:29 the differences between step into step over and step out. 9:33 So let's stop execution and we'll run our app again and we can stop up here. 9:37 I can hide this sim for a minute. 9:43 You saw when we stepped in and we found ourselves inside of these calls. 9:45 But if we step over, let's start by just running to here, 9:50 you'll see that we just jump to the next call. 9:54 We still executed the call, the debugger just won't stop inside and 9:57 show us that interim step. 10:01 But make no mistake the code still executes. 10:03 Watch this. 10:06 Now just for kicks, let's step in and 10:08 then let's set a break point here inside this call. 10:12 Then we can step in and we're to the next line. 10:17 Let's try stepping over again. 10:22 You see we do stop inside this call because we placed a break point there. 10:27 If we wanna get back to where we came from we can step out. 10:32 And then we go up one level in the hierarchy. 10:38 Again the code still runs. 10:41 We just won't see it stop until we've ascended a level. 10:43 All right we do have this break point down here so 10:46 let's just hit play and it'll take us down there. 10:48 So we can see up here, our products array has nine values and we can use these 10:55 disclosure triangles to look at all the information that's in there. 11:00 Just for kicks, we can check iPod and yet we do have a year introduced here. 11:03 So our problem must be downstream, so 11:08 to speak, later in the execution of our app, then right here. 11:11 Now this variable has been declared here outside of the class. 11:16 So it's not showing up in our variables window, but most variables will. 11:20 We can also head over here into our console and 11:25 we can manually print the objects so we can po products. 11:28 And you'll see here we get a list of our product objects, there are nine of them. 11:32 We can also type p products that's no O and you'll see that we get a nice printout 11:39 of essentially what we saw when we mouse over here and expanded the triangles. 11:46 We've got all our objects. 11:52 And it shows their titles, hardware type, intro price, year introduced. 11:54 Now printing things to the console was a lot more common back when the variable 11:59 navigator wasn't so robust, but 12:03 this is still a very useful thing to do if you know just what you're looking for. 12:05 So let's say we don't want all of this gobbledygook here. 12:10 Let's say we just want the title of the first element in the array. 12:14 For that we could go, po products .title. 12:18 Whom iPhone, as you can imagine this is 12:23 a really useful way to inspect data when you 12:27 know just what you're looking for. 12:32 This is also a really useful way to inspect data you're getting from or 12:38 sending to a server API. 12:41 Often you'll find that getting the data is easy but figuring out the format 12:44 is a little bit harder and this gives you a quick way to view all of that. 12:48 Now to get rid of all the stuff you just click the trashcan. 12:52 Now I'm gonna remove a couple of these break points by dragging them into 12:56 the pane and let's run again. 13:00 Okay now that we've done that we can see that our simulator 13:04 has loaded the main table. 13:07 Like we saw a moment ago. 13:09 We have the value you want for iPod. 13:11 Let's tap on iPod. 13:14 Still no price makes sense. 13:17 We haven't changed anything. 13:18 Now for our small app we know that this screen that showing our bug here 13:20 is the detail view. 13:25 Let's open up that class and see where we might drop in a break point or two. 13:27 Add to the detail view and if we start at the top and we start reading through, 13:34 we've got our properties, we've got, well, we've got a view will appear. 13:41 Okay, let's try dropping into break points here. 13:48 We can also put one up at the top and one of the very end. 13:53 Now if we go back to our sim, go back to the main view and hit iPod again. 13:57 We'll see that we stopped right here as our detail view is trying to appear. 14:04 If we look at our variables here we see that we don't actually have a string for 14:10 our price string yet maybe we're on to something. 14:14 Let's continue the execution. 14:17 We can continue again. 14:21 Now we have our priceString of 399. 14:25 Take a second and see if you can figure out how that happened. 14:27 Well, we didn't create our priceString constant until this break point. 14:33 And then we set it to the formatted version of our introPrice. 14:39 Here, so wasn't gonna show a value in priceString until we got down to here. 14:42 Now I don't expect everyone to be able to just read this 14:49 unfamiliar code like it's plain English, but if you take a minute and 14:52 focus on all the pieces you do know you'll be able to figure out a lot of what it 14:55 means especially with the descriptive naming that this author used. 14:59 Practicing reading unfamiliar code when debugging is a really, 15:03 really good way to increase your comfort as a programmer. 15:06 So while we're here, 15:09 it's worth pointing out another cool debugging feature in Xcode. 15:10 You can mouse over variables that are in scope and see their value. 15:14 So we can mouse over price string over here and we get its current value. 15:18 Now when I say current value, I don't mean its value on this line. 15:24 I mean it's value once we've executed as far as our code has executed. 15:29 Anywhere we mouse over priceString. 15:33 We're gonna get the current value of priceString. 15:36 One other thing to highlight is the instruction pointer. 15:40 That's this little arrow right here. 15:43 When you're paused at a break point you can slide it forward or 15:45 back and then you can restart. 15:48 And your execution will restart from that point. 15:54 Bear in mind when you do this you're changing the flow of your code. 15:58 So if you move forward and let's say skip a line that creates a variable. 16:01 Your app might crash when it tries to use that variable since it won't be found. 16:06 Okay, so our price string had a value of 399 but it's not showing up here. 16:11 Any ideas, did we miss anything? 16:16 Let's continue and again we still see no price. 16:19 I tried to open the detail view controller again, and so 16:25 it sends us to this break point inside our class. 16:28 If we mouse over priceString, it has no value, yet hasn't been assigned. 16:31 Let's continue to our line. 16:36 This time, let's step in rather than just continuing to our next break point. 16:38 We see we get popped into a few different spots. 16:43 And that's good. 16:46 Remember this is a great way to see how your code flows, if you get lost. 16:48 Okay, we're almost down to our break point and we've come down to this line. 16:53 We have a method here that says stock or price pending. 16:58 Let's see what happens when we step into that. 17:04 Okay here we are inside of our stock or price pending method. 17:07 And we see a few comments, let's see if they offer any insight. 17:12 It looks like we're checking for products with low stock or variable pricing. 17:15 And this appears to be a plug version for the 1.0 release and 17:21 in 2.0 we're actually going to be pinging the inventory API. 17:25 And the below products that looks like the iMac and the iPod have low inventory. 17:29 Now I check my notebook from my notes and 17:35 it looks like those two are the products which weren't showing our price. 17:38 Now it's probably obvious to you why that's happening. 17:44 It seems that if we hit either of those conditional statements 17:46 we're setting the price label hidden property to true. 17:51 In other words we're hiding the label. 17:54 So we had the string value we need we're just hiding it in the user interface. 17:56 Now, this all sounds good and the story I just told you is compelling but 18:02 how can we be sure it's actually happening? 18:06 Well, why don't we drop a break point in here and here and 18:08 run our app you see we tapped an iPod and we did wind up here and we continued. 18:15 In case you're not convinced let's try that again. 18:21 We can go back here and just for fun we'll touch iMac. 18:27 Run, run and see we're hitting right inside 18:31 here where we're hiding that price label. 18:36 So it seems like what the developer did was hide the price so 18:42 folks couldn't order the item. 18:45 I guess they want customers to call and 18:47 ask about low inventory items or something. 18:49 Just for kicks, why don't we replace this line with something more informative? 18:51 How about priceLabel.text 18:55 = Please call for pricing. 19:01 Okay we would wanna comment that out. 19:08 And we can copy that there and of course in real life we wouldn't wanna 19:11 leave a magic string hanging around here, we'd wanna create a constant 19:16 somewhere with higher scope so we could use it throughout the app. 19:21 But we're just learning about debugging so we'll leave that here for now. 19:26 And we're gonna want run this to test and we'll wanna get rid of our break 19:30 points but just for fun we'll do that in the break point navigator. 19:33 Just here and we'll run our code again. 19:38 Touch on iPod. 19:47 Here we go. 19:49 Please call for pricing. 19:49 iPhone. 19:51 Still as it where and we can check iMac. 19:52 Please call for pricing. 19:56 Now this looks okay, but 19:58 I would definitely make a note to call the product owner or product 20:00 manager in charge of this app to find out how they really wanna handle this issue. 20:03 Since ultimately it's up to them not me, the developer. 20:08 Okay, we've seen some of what Xcode has to offer in terms of debugging tools. 20:12 But to be honest, we don't just spend our lives writing code. 20:16 Just because you might be a professional developer doesn't mean you won't encounter 20:19 bugs elsewhere in your office, or perhaps at your next family picnic. 20:22 That's why I always keep one of these handy. 20:27 It's fast, cheap, and perfect for 20:29 fighting off whatever unwanted creatures may come your way. 20:31 All righty, see ya real soon. 20:36
You need to sign up for Treehouse in order to download course files.Sign up