In the last lesson, we added the logic to progress to the next question into our Quiz Brin. However, 1
Xcode gave us an error as soon as we tried to change the questionNumber, and the reason is we're trying 2
to change a property of our struct from its methods. 3
Here is our struct blueprint. 4
And here when we actually use that struct, that quizBrain, well, this is the actual struct object. 5
So each of these properties, say, the questionNumber or the quiz, 6
well, they are associated with that object created from the struct, and they cannot be changed. 7
The only way we can change them from inside one of our methods is to mark those methods with the keyword 8
mutating. 9
In other words, we have two kinds of methods in our structure. 10
The first kind is a method that doesn't change anything and just returns a value like getProgress. 11
And the second method is one that changes a property in the Quiz Brain. 12
The only thing we have to do is to help identify which functions will change a property in the 13
Quiz Brain. 14
That's why we have to mark our next question method as mutable. So if we click on this suggestion, you 15
can see that it's telling us one of the fixes is to mark this method as mutating to make 'self' mutable. 16
So if we click Fix, you can see it as the mutating keyword before the func keyword. 17
And what this tells the computer is that when this function is run, it will replace the old value of 18
questionNumber with a new value. 19
So every time you create a struct, and inside one of the functions or one of its capabilities, you need 20
to be able to update one of the properties, 21
so a var or changeable property, 22
you have to do that inside a mutating function. So if we run our app right now, you can see there are 23
app works perfectly just as it did before. 24
But in this case, we've shifted all of the quiz logic into a separate structure called the QuizBrain 25
and our controller or the ViewController now is only responsible for delegating these tasks to the 26
quizBrains, say,"Hey, quizBrain, 27
give me the next question," or "Hey, quizBrain, check this answer for me," or "Get me the questionText," 28
and the control is now talking to our model to be able to make the quiz work. And our controller is also 29
talking to our user interface, namely changing the button background colors or updating the UI every 30
time we go to the next question. And the code is now much easier to understand, more reusable and more 31
modular. 32
So we've now implemented the model-view-controller design pattern to our Quizzler App. To practice coding 33
in this MVC design pattern, 34
we're going to set you a challenge. And the challenge is to make our app be able to keep track of the 35
user's score. 36
So what you're gonna do is you're gonna create a new label and you're going to drag it to the very top 37
of our vertical stack view, so you get to place it here. And then, we're going to modify some of the attributes 38
or properties of this label. 39
And I'm going to change the text color to white to be able to see it against the dark background. 40
Now, the next thing I want to do is I'm going to create an IBOutlet that links from this label to my 41
view controller. 42
So I'm going to create it just about maybe here and I'll call it a scoreLabel. 43
Now, finally, we're gonna go to our view controller. And under updateUI, I'm going to set the scoreLabel's text 44
property to equal to, say, "Score:" 45
And then I'm going to use my string interpolation to insert a method to get from my quizBrain. 46
So I'm gonna tap into my quizBrain and I'm gonna say getScore. 47
So here comes the challenge for you. At the moment, 48
there is no such thing as getScore in quizBrain. 49
So pause the video and make sure that all of your score tracking and score managing and score keeping 50
functionality happens inside the QuizBrain. 51
And if you manage to successfully complete this challenge, this error should, of course, go away. 52
But, also, we should be able to see the score start out with zero. 53
And every time we get an answer right, the score will go up by 1. 54
So if we get an answer wrong, nothing changes, but all the correct answers will increase our score. 55
And once we get to the end of our quiz and it resets, well, our score should also reset to zero. 56
So this is the challenge for you to practice using MVC and making sure that this quiz-related functionality 57
lives inside the QuizBrain. 58
Pause the video now and try to complete this challenge. 59
All right. 60
So here comes the solution. 61
We know that we can't write any code in our view controller which is solely responsible for updating 62
the UI and talking to our model. 63
So we have to make our model be able to perform the functionality of keeping track of score and sending 64
it back via this method called getScore. 65
So if we go over to the QuizBrain, this is where all of the heavy lifting is going to happen. 66
So the first thing I'm going to do is I'm going to create a variable that's going to keep track of the 67
score in a similar way that I'm keeping track of the questionNumber that the user is on. 68
The score is going to start out with a value of zero. 69
But when is it going to get increased? 70
Well, whenever we check the user's answer and it matches the correct answer, 71
well, in that case, not only do we return true and tell our view controller that the user got it right, 72
but we also increase the value of score by 1. 73
Now, we're not going to do anything to punish them when they get it wrong. 74
But we do have to address the issue of the mutating function because, again, we're modifying one of the 75
properties of a struct 76
so, therefore, we have to mark this function as mutating, so that we rebuild our structure with a new value 77
for score. 78
Now, the next thing we need to do is to be able to send this score back through the function that the 79
view controller cause which is called getScore. 80
So I'm going to copy that. And in my QuizBrain just above my getQuestionText, I'm going to create a 81
new function called getScore and this is going to return the score which is, of course, a integer or 82
a whole number. 83
And it's simply going to return the value of our score property which lives inside our Quiz Brain. 84
So now the very last thing we need to do with score is to remember to reset it down to zero when our 85
quiz restarts. 86
So not only do we reset our questionNumber, we also reset our score. 87
And now if I run my app, firstly, my errors should go away because this method now exists, and also I'm 88
now able to keep track of the user's score. when they get a question right, 89
the score goes up, and when they get to the end of the quiz, the score resets. 90
So did you manage to get that right? 91
If you want more practice on using the MVC design pattern to be able to switch out or modify just the 92
Quiz Brain component and leave everything else as is, 93
we've got an optional challenge for you. And the challenge here is if you go into the README, you can 94
see that in addition to the default quiz, we've also got a section called the Multiple Choice Quiz. 95
So if you were to copy all of these multiple-choice questions and replace the questions that's currently 96
inside our quiz array with the multiple-choice questions, can you figure out how to modify the code in 97
the app so that you end up with a multiple choice quiz? 98
And if you manage to successfully complete the challenge, then this is what your app will look like. And 99
it's now modified to be able to serve up three possible answers, and then the user can select the answer 100
as one from the three. 101
So there's a number of things that you'll have to modify in the app for this to be able to work. 102
And if you want to tackle this optional challenge, then go ahead and replace the quiz array now. 103
And once you're done, you can compare your answer, against my answer by downloading the completed project 104
for the Multiple Choice Quiz which we'll be able to find, of course, in the course resources. 105
But either way, no matter what you choose, I'll see you on the next module.