0 1 00:00:00,090 --> 00:00:06,270 In the last lesson, we managed to create a single array which contained three questions and we were able 1 2 00:00:06,270 --> 00:00:09,620 to show it on screen and show each of the questions. 2 3 00:00:09,720 --> 00:00:14,940 Now, in this lesson, we're going to try and figure out how to be able to check to see if they got the 3 4 00:00:15,000 --> 00:00:16,530 answer correct, 4 5 00:00:16,530 --> 00:00:23,310 so whether if they chose the right answer to each question. And in the process, we'll also learn how to 5 6 00:00:23,310 --> 00:00:26,830 work with a two dimensional array in Swift. 6 7 00:00:27,060 --> 00:00:33,930 Now, in order to do this, we need to somehow associate an answer with each question, right? 7 8 00:00:33,930 --> 00:00:40,260 We need to be able to say that, well, maybe this one should be true and this one should be True, 8 9 00:00:40,260 --> 00:00:42,080 but this one should be False. 9 10 00:00:42,450 --> 00:00:49,930 So how can we associate two pieces of data together even though our quiz lives inside an array? 10 11 00:00:50,670 --> 00:00:57,660 Well, one way of doing this might be through the use of an array within an array or what you might call 11 12 00:00:57,750 --> 00:00:59,480 a 2D Array. 12 13 00:00:59,650 --> 00:01:04,090 So far, the arrays that we've been creating look something like this. 13 14 00:01:04,090 --> 00:01:12,080 We have as many items as we need or separated by a comma and placed inside a single array. 14 15 00:01:12,100 --> 00:01:14,610 So this is our collection of items. 15 16 00:01:14,710 --> 00:01:22,450 Now, we can also create a 2D Array where we have individual arrays. So there's three arrays, in this 16 17 00:01:22,450 --> 00:01:29,440 case, each with two items all packaged inside a larger array. 17 18 00:01:29,440 --> 00:01:35,740 So how would you retrieve a single entry out of a two-dimensional array? When we had a one-dimensional 18 19 00:01:35,740 --> 00:01:42,200 array, retrieving items was pretty straightforward. In order to retrieve items out of our array, 19 20 00:01:42,220 --> 00:01:49,410 we simply added a set of square brackets and a number after the name of the array. And that number, 20 21 00:01:49,430 --> 00:01:56,560 in this case, "i," refers to the position of the item that we want. Now, if we had a 2D Array on the other 21 22 00:01:56,560 --> 00:02:03,730 hand, in addition to adding a first set of square brackets where we're picking through the outer layer 22 23 00:02:03,730 --> 00:02:05,170 of arrays. 23 24 00:02:05,440 --> 00:02:13,090 Now, that we've picked out the item that is at this position, let's say, this one which is position 2, well, 24 25 00:02:13,090 --> 00:02:15,720 now we have access to yet another array. 25 26 00:02:15,760 --> 00:02:21,500 And in order to pick from this inner array, we have to tag on another set of square brackets in order 26 27 00:02:21,500 --> 00:02:25,760 to pick between these two items in the inner array. 27 28 00:02:25,840 --> 00:02:30,850 So here's a question. If we had an array that was a 2D Array that looks like this, 28 29 00:02:30,880 --> 00:02:37,960 so we have 1, 2, 3 inside its own array, 4, 5, 6 in its own array, 7, 8, 9, and then these three 29 30 00:02:37,960 --> 00:02:41,540 arrays are packaged into another array. 30 31 00:02:41,740 --> 00:02:45,390 Well, how do you get hold of the number 9? 31 32 00:02:45,430 --> 00:02:46,180 Pause the video, 32 33 00:02:46,180 --> 00:02:47,240 have a think about that. 33 34 00:02:47,260 --> 00:02:49,460 What would your code look like? 34 35 00:02:51,090 --> 00:02:59,550 Well, in this case, the positions of the outer array are 0, 1, and 2, and then the positions inside the array 35 36 00:02:59,550 --> 00:03:02,070 are also at 0, 1, and 2. 36 37 00:03:02,080 --> 00:03:07,950 So in order to get hold of this number 9, we first have to tap into our array, and then specify that 37 38 00:03:07,950 --> 00:03:10,710 we want the array that at position 2. 38 39 00:03:10,740 --> 00:03:12,690 So it's this one, 7, 8, 9. 39 40 00:03:13,170 --> 00:03:18,990 And then within this array of 7, 8, 9, we then specify the position of the item we want which is, again, 40 41 00:03:18,990 --> 00:03:20,430 at 0, 1, 2. 41 42 00:03:20,430 --> 00:03:27,660 So now we have array square brackets 2, square brackets 2 in order to get that number 9 out of this 42 43 00:03:27,660 --> 00:03:31,260 2D Array. Coming back to all code here, 43 44 00:03:31,360 --> 00:03:38,890 we currently have a 1D Array, and we can turn it into a 2D Array by simply making each of the items 44 45 00:03:39,160 --> 00:03:40,840 a array itself. 45 46 00:03:40,900 --> 00:03:48,700 So we now have a question and a answer, and I'm keeping it simple by making the array keep the same type 46 47 00:03:48,700 --> 00:03:49,180 of data. 47 48 00:03:49,210 --> 00:03:51,960 So they're both gonna be strings, right? 48 49 00:03:52,120 --> 00:04:01,800 So let's go ahead and modify the rest of these. So we now have three arrays within an array. And if we 49 50 00:04:01,800 --> 00:04:09,480 take a look at the data type of our quiz constant, you can see it's now a 2D Array of strings. So it's 50 51 00:04:09,480 --> 00:04:12,760 got two brackets around each side. 51 52 00:04:13,180 --> 00:04:20,380 And now if we wanted to pick out the first question out of our quiz array, then instead of simply specifying 52 53 00:04:20,380 --> 00:04:27,940 quiz[question number,] we also have to tag on a zero at the end because now it's going to pull out the 53 54 00:04:28,210 --> 00:04:34,300 first array using the question number which starts out being equal to zero, and then within that array, 54 55 00:04:34,330 --> 00:04:36,130 we want to get the first item, 55 56 00:04:36,130 --> 00:04:38,830 so the one at position 0. 56 57 00:04:38,830 --> 00:04:45,920 So this would be all code overall. So now that we have the quiz in a 2D Array, 57 58 00:04:45,930 --> 00:04:54,470 well, let's check the answer that we have in our 2D Array against the answer that the user chose. 58 59 00:04:54,480 --> 00:04:58,110 So, firstly, we have to figure out what answer they chose. 59 60 00:04:58,110 --> 00:05:04,530 So right here, I'm going to create a new constant called userAnswer and I'm gonna set it to equal the 60 61 00:05:04,590 --> 00:05:12,860 sender.currentTitle. So whichever title they chose from the two buttons are linked to my IBAction, 61 62 00:05:13,170 --> 00:05:16,250 so True or False. 62 63 00:05:16,310 --> 00:05:23,870 Now, this userAnswer is going to be equal to the string true or the string false. 63 64 00:05:23,870 --> 00:05:28,280 So we can now use it to check against the actual answer. 64 65 00:05:28,280 --> 00:05:35,970 Now, the actual answer is going to be equal to the quiz array at position 1, 65 66 00:05:36,020 --> 00:05:36,330 right? 66 67 00:05:36,650 --> 00:05:39,630 So similar to how we got our quizQuestion, 67 68 00:05:39,740 --> 00:05:46,700 we're going to set this equal to the quiz array and then the first layer is going to be questionNumber. 68 69 00:05:46,730 --> 00:05:51,940 So it's going to be one of these arrays depending on which question we are on. 69 70 00:05:52,460 --> 00:06:00,260 And then the second one is going to be position 1 because that's where the answers live. They're all at position 70 71 00:06:00,260 --> 00:06:01,990 one inside the array. 71 72 00:06:03,360 --> 00:06:09,540 So now in order to check to see if the user got the answer right, all we have to do is create an if statement 72 73 00:06:09,750 --> 00:06:17,510 and check to see if the userAnswer is equal to, so double equals, to the actual answer, 73 74 00:06:17,520 --> 00:06:20,130 well, then in that case, that means they got it right, 74 75 00:06:20,130 --> 00:06:20,400 right? 75 76 00:06:21,210 --> 00:06:24,180 So we'll just print "Right!." 76 77 00:06:25,230 --> 00:06:31,410 Otherwise, namely "else," well, they probably got it wrong because their answer doesn't match the actual 77 78 00:06:31,410 --> 00:06:32,100 answer, 78 79 00:06:32,250 --> 00:06:35,130 so we'll right wrong. 79 80 00:06:35,130 --> 00:06:42,180 Now, if we run our app, we should be able to see that question checking mechanism in action. 80 81 00:06:42,300 --> 00:06:47,790 So if we run our app, you can see that if I press Four plus Two is equal to Six, 81 82 00:06:47,790 --> 00:06:48,720 yeah, that sounds right, 82 83 00:06:48,720 --> 00:06:50,230 So let's press True. 83 84 00:06:50,430 --> 00:06:52,000 We got it right. 84 85 00:06:52,020 --> 00:06:54,180 Five-Tthree is greater than One, 85 86 00:06:54,750 --> 00:06:57,000 And then finally, Three + Eight is less than Ten. 86 87 00:06:57,000 --> 00:06:58,710 That's definitely False. 87 88 00:06:58,710 --> 00:07:07,200 So now we get our last answer, but then our app crashes because we, again, fall out of the range of our 88 89 00:07:07,200 --> 00:07:08,940 quiz array. 89 90 00:07:08,940 --> 00:07:11,910 We don't have a fourth question. 90 91 00:07:12,030 --> 00:07:16,640 So we've got a working quiz app now, although it's a pretty buggy one. 91 92 00:07:16,800 --> 00:07:19,190 And your app crashes on a user's phone, 92 93 00:07:19,230 --> 00:07:20,370 they won't know what's happened, 93 94 00:07:20,370 --> 00:07:23,000 they won't know that the index is out of range. 94 95 00:07:23,010 --> 00:07:25,070 They'll just think that you've made a terrible app. 95 96 00:07:25,170 --> 00:07:30,850 So let's fix this and help you maintain your reputation as an app developer. 96 97 00:07:31,250 --> 00:07:34,190 So the first thing that we need is a safety check. 97 98 00:07:34,400 --> 00:07:37,070 So inside the answer button pressed, 98 99 00:07:37,070 --> 00:07:44,120 before we increase the questionNumber, let's first check to see if we're actually at the end of the quiz. 99 100 00:07:45,170 --> 00:07:47,390 And I'd like to pose this as a challenge to you. 100 101 00:07:47,450 --> 00:07:53,810 Can you use an "if" statement and only increase the questionNumber as long as we're not yet at the end 101 102 00:07:53,810 --> 00:07:55,100 of the quiz. 102 103 00:07:55,100 --> 00:07:58,660 I'll give you a few seconds to pause the video before I show you my solution. 103 104 00:08:01,820 --> 00:08:02,250 Okay. 104 105 00:08:02,320 --> 00:08:04,480 Here's my sample solution. 105 106 00:08:04,480 --> 00:08:12,520 So in our case, we want to prevent the questionNumber from being increased passed number 2. You might think 106 107 00:08:12,520 --> 00:08:17,740 that you can simply write the following: If questionNumber is less than 3, then increased 107 108 00:08:17,740 --> 00:08:25,140 questionNumber by 1, or you might have written it like this, if questionNumber is less than quiz.count, 108 109 00:08:25,450 --> 00:08:30,250 so the length of our array, then increase questionNumber by 1. 109 110 00:08:30,250 --> 00:08:36,730 But let's double-check this by running our app again. Even though we think we might have fixed the problem, 110 111 00:08:36,790 --> 00:08:38,790 you'll notice something quite peculiar. 111 112 00:08:39,220 --> 00:08:43,930 So if I press on the third button, my app still crashes, 112 113 00:08:43,930 --> 00:08:45,130 what's going on? 113 114 00:08:45,130 --> 00:08:48,110 Well, the line that's being highlighted is right here. 114 115 00:08:48,220 --> 00:08:51,140 So this is, obviously, the line that's crashing my app. 115 116 00:08:51,220 --> 00:08:54,670 And the reason is because the index is out of range. 116 117 00:08:54,880 --> 00:08:59,840 So the only thing that has an index that changes is my questionNumber. 117 118 00:09:00,070 --> 00:09:06,430 And we can see down here that the questionNumber was, again, allowed to go to 3, even though we said 118 119 00:09:06,610 --> 00:09:12,430 don't increase the questionNumber, unless the questionNumber is less than the quiz count. 119 120 00:09:12,910 --> 00:09:14,110 So what's happening here? 120 121 00:09:14,110 --> 00:09:21,400 Well, here's what's happening. When the questionNumber is equal to 2, 2 is less than quiz.count which 121 122 00:09:21,400 --> 00:09:22,870 which is 3, 122 123 00:09:22,900 --> 00:09:27,100 well, now in this case, questionNumber increases by 1. 123 124 00:09:27,100 --> 00:09:35,260 So questionNumber is now 3. And then it goes into the updateUI and it tries to update the UI by getting 124 125 00:09:35,320 --> 00:09:40,570 the item at position 3 out of our quiz which is what crashes our app. 125 126 00:09:40,600 --> 00:09:46,690 So instead of simply checking if the quizNumber is less than quiz.count, we actually have to increase 126 127 00:09:46,690 --> 00:09:48,590 this by 1. 127 128 00:09:48,610 --> 00:09:55,540 So now when it gets to questionNumber 2, then it's going to add 1 to it, 128 129 00:09:55,550 --> 00:09:58,220 so we never go beyond 2. 129 130 00:09:58,480 --> 00:10:00,610 And now if we run our app again, 130 131 00:10:03,920 --> 00:10:10,780 you'll see that we've solved our bug and it no longer progresses beyond the last question. 131 132 00:10:11,240 --> 00:10:13,240 Here's another challenge for you. 132 133 00:10:13,520 --> 00:10:19,410 See if you can change the code to make the quiz restart from the beginning when it reaches the end, 133 134 00:10:19,490 --> 00:10:24,650 so you should end up with a never-ending quiz, and it'll look something like this. 134 135 00:10:24,650 --> 00:10:26,990 So here we've got our first question, 135 136 00:10:27,140 --> 00:10:28,390 our second question, 136 137 00:10:28,460 --> 00:10:30,020 third question, 137 138 00:10:30,050 --> 00:10:36,290 back to the first question. So pause the video and try and see if you can get this functionality working 138 139 00:10:36,290 --> 00:10:36,920 in your app 139 140 00:10:39,870 --> 00:10:40,170 All right. 140 141 00:10:40,200 --> 00:10:41,640 So how do we achieve this? 141 142 00:10:41,640 --> 00:10:47,700 Well, the place where we reach the end of the quiz is, of course, when the questionNumber plus 1 is 142 143 00:10:47,700 --> 00:10:49,530 actually equal to the quiz count. 143 144 00:10:50,010 --> 00:10:52,350 So how do we catch that scenario? 144 145 00:10:52,500 --> 00:10:55,200 Well, we can simply add an "else" statement. 145 146 00:10:55,350 --> 00:10:59,570 So if it's gone beyond the number of items we have in our quiz, 146 147 00:10:59,670 --> 00:11:03,890 well, then we're simply going to set the questionNumber back down to zero. 147 148 00:11:03,930 --> 00:11:12,640 So the next time we update our UI, we fetch the first question out of our quiz again, and that means our 148 149 00:11:12,640 --> 00:11:19,640 quiz will loop on and on endlessly at least until the user gets bored. At this point, 149 150 00:11:19,670 --> 00:11:21,630 we're showing new quiz questions. 150 151 00:11:21,680 --> 00:11:25,220 We're checking the user's answer and our app is no longer crashing. 151 152 00:11:25,580 --> 00:11:30,770 So now is a good time to restructure and reorganize our code. 152 153 00:11:30,770 --> 00:11:35,600 Currently, one of the biggest eyesores in our code is this 2D Array. 153 154 00:11:35,660 --> 00:11:36,910 It's hard to read. 154 155 00:11:36,920 --> 00:11:42,110 It's hard to understand, not just for you, for any programmer. So how can we make this better? 155 156 00:11:42,500 --> 00:11:51,120 Well, we could use a Swift structure to create a question structure that contains a title property, 156 157 00:11:51,290 --> 00:11:54,950 so the title of the question, and then a answer property, 157 158 00:11:54,950 --> 00:11:57,570 so the answer of each question. 158 159 00:11:57,740 --> 00:12:05,390 So if you know all about Swift structures and you can create a structure to capture our quiz array so 159 160 00:12:05,390 --> 00:12:13,130 that we get rid of our 2D Array, and instead have an array of quiz items each with a title property 160 161 00:12:13,280 --> 00:12:17,780 and an answer property, then you can probably skip the next Swift Deep Dive. 161 162 00:12:18,230 --> 00:12:22,810 But if you've never heard of structures, then I recommend heading over to the next lesson 162 163 00:12:22,880 --> 00:12:28,130 where we're gonna do a Deep Dive on that, and more. So the choice is yours and I'll see you on the next 163 164 00:12:28,130 --> 00:12:28,910 lesson you choose.