All right. 1
So this just one last thing left to do. 2
If we were baking a cake, we wouldn't need to tidy up and wash everything and make sure that we're leaving 3
the place as brand spanking clean as we found it. 4
And in our case, we need to tidy up our code so that if we come back to it in a month or in a year or 5
if somebody else were to collaborate with us on this project that they actually understand what's going 6
on and it's not a whole jumble of mess. 7
So the first thing that we should try to eliminate are places where we have a lot of hard coding. 8
So one of the most obvious ones is this 9
count number here, because why would it be? 10
Because safe in the future, we decided to upgrade our Twitter API membership to their premier or enterprise 11
versions and we stopped paying them so that we can get more tweets back in the same query, say, a thousand tweets 12
or 10,000 tweets. 13
Then we don't want to be digging through this count 14
and also here in the for loop changing it or forgetting to change it which is even worse because we'll 15
end up with bug that we don't know the reason for. 16
So let's make sure that we change this into a constant up here so that when we decide to update that, 17
we can easily find it. 18
So let's call it something like tweetCount and let's set it to 100, and we can replace it 19
now over here, and also inside our for loop. 20
All right. 21
So that's one thing checked off, removing some hardcoding. 22
Now, the next thing that we need to do is to make some methods and split up the functionality of our code 23
so that it's not all inside our IBAction because having this large a chunk of code, and especially if 24
we're going to add to it, is not great when it comes to debugging. 25
So let's go ahead and move some of this code into some distinct functions. 26
So a function that we might have is something like fetchTweets, and another one that we might have is 27
makePrediction. 28
And finally, we might have one that simply updates the UI, 29
so that in the future if we were to have any problems with fetchingTweets, for example, we weren't getting 30
any tweets back from Twitter, then we would know to look inside here and look for the method that fetches 31
our tweets. 32
And if we had problems with making the prediction, then equally, we can navigate to this method. 33
And this just makes our code so much more manageable 34
and a lot more modular. So let's move the part that fetches our tweets which currently it's kind of all 35
entangled with the predictions. 36
So I'm going to take everything inside our IBAction here and I'm just going to cut it and I'm going 37
to paste it into our function fetchTweets. 38
Now, be sure to remember to actually call fetchTweets, so that when the user presses the predict button, 39
it actually goes to this function. 40
Now, inside this function, the parts that make the prediction, 41
I'm going to take away and put it into the makePrediction function. 42
So I'm going to take this entire "do catch" block, so everything that's involved in making the prediction 43
and place it inside the function, that is our makePrediction function. 44
So, now our fetchTweets function only has enough functionality to search Twitter and make the request 45
to fetchTweets from the Twitter API. And in our makePrediction function, we're able to do all of the 46
rest which needs further splitting up. 47
But before we do that, we have one problem where it says, "Use of unresolved identifier 'tweets.'" 48
And that's because when that code was over here, we had our tweets right up here which we appended to 49
inside our for loop. 50
But now what we have to do is we need to call our makePrediction here, 51
and so that it triggers this method, and we're going to pass in this tweet array. So this makePrediction 52
is going to take a single parameter and I'm going to call it with tweets. 53
So this is going to be of type TweetSentimentClassifierInput array. 54
And when we call the method, we're going to use the external parameter. And inside the function, we're 55
still going to use the same parameter called tweets, 56
so that gets put over here. 57
Now, when we call this method, we, of course, now have to use "with." 58
And the thing that it is expecting is of type TweetSentimentClassifierInput array which is, of course, 59
our tweets 60
All right. 61
So that's fixed, that part. 62
Now, the next thing we need to do is once we've gotten our sentimentScore, we need to update the UI, and 63
all of that is inside this section here. 64
And so let's go ahead and cut that and paste it into our updateUI method, so that we know the part, so 65
that it's separated from the functionality of making predictions. 66
Now, we have another problem here, 67
namely that the sentimentScore doesn't exist outside of the scope of makePrediction because we created 68
it in here. 69
Now, one of the ways of solving this, that we've done previously when we had less experience with Swift, 70
is to simply make this a global variable 71
and while that's very, very easy to do. Having a global variable comes with some of its own problems. 72
For example, if you have a global variable inside your class ViewController, 73
If I create a new object of ViewController, I can affect the value of that global variable. 74
Now, if I have it as a local variable that's only available inside this method, 75
I won't be able to accidentally mess with this value from other classes, 76
and this is an important distinction between global and local variables. 77
Now,if you want to read more about when you should use global and when you should use local variables, 78
in the resources list for this lesson, I've included a link so that you can do some further background 79
reading on this topic. 80
Now, over here, we have to solve the short-term problem of how do we use this local variable 81
sentimentScore. 82
Well, at the point when we need to call our update UI function which is hereafter the for loop, we're 83
going to call updateUI and we're going to pass in our sentiment score. 84
And that means, of course, we need to update this method, 85
so that it takes a sentimentScore as an integer, and our errors should now go away, because we are calling 86
the method update UI passing in the latest sentimentScore that's tallied up from all 100 tweets, and 87
then that gets passed into this method and gets used in the "if" statement. 88
Now, we just have one error left which is that makePrediction is a method call that we're making inside 89
a closure. 90
So we have to change this to have the "self" marker in front, so that we know explicitly that it's a method 91
in the current class. And now, there you have it. 92
Here's our refactored code eliminating global variables, eliminating any hardcoding, and splitting 93
off our functionality into distinct modules making our code much easier to maintain and to understand 94
when we come back to it or when we collaborate with other people. 95
So, of course, there are further ways of simplifying or shortening the code, but there's always a sweet 96
spot between clarity of code and the length of code. 97
So, personally, I feel like this is acceptable. But if you wish to do further refactoring, then feel free 98
to keep going. Or if you want to add more features to this app and make it even more interesting using 99
your imagination, then I really look forward to all of your creation and seeing them in the Q & A section. 100
Be sure to show off anything fantastic that you've come up with. 101
So that's all from me for this module. 102
I hope to see you in the next module where I'll be back with more project and more challenges. 103
So see you there.