All right. 1
So in the last lesson, we went about setting up our project making sure that we incorporated our 2
TweetSentimentAnalysisClassifier, as well as this external framework, called sSwifter. 3
So we're now all ready to go. 4
And the first thing we're going to do is we're going to go into our ViewController.swift file 5
and we're going to import that framework that we included in the last lesson, 6
and that's Swifter iOS. 7
Now, the next thing to do is to check the documentation for this Swifter framework. 8
And you can see that under Usage, we've already done installation, 9
so we now need to use it. 10
And it tells us that it can be used using three different kinds of authentication protocols that Twitter 11
allows. 12
And you can specify which one you want to use 13
and they give you the example code for how you would do that. 14
Now, you can see over here under our app, we've got a Consumer API Key. 15
And if you click on this link where it says, "Manage keys and access" tokens, then it takes you to an area 16
where you've got your API Key and your API Secret and that's everything that you need to do in order 17
to authenticate yourself as a developer to try and grab data from the Twitter API. 18
So if we head back over here, you can see the one where we have a Consumer Secret as well as a Consumer 19
Key is the second one. 20
So I'm just gonna go ahead and copy this line of code. 21
And we're going to go ahead and paste it just under our IBOutlets. 22
Now, I have to add a "let" here so that we create a new constant code swifter and it's going to be initialized 23
using a consumerKey and consumerSecret. 24
So we have to replace these two placeholders with our actual values from the Twitter app. 25
So if you head over to your Twitter Application Manager, remember, this is under apps.twitter.com. 26
And there you have to log in into the account that you used to set up your Twitter application and then 27
following what we did before going to Keys and Access Tokens, you should be able to have a Consumer Key, 28
this is your API Key which you are going to paste in here as a String, 29
so remember to enclose it inside some quotation marks, and also make sure there's no spaces between the 30
beginning and the end and the quotation marks. 31
And secondly, we're going to copy our Consumer Secret. 32
Now, notice, it's actually quite long, 33
so just double click, 34
and we're going to copy it over here, again, inside some quotation marks. 35
So, now this line of code will use Swifter to initialize a new instance of this framework 36
and it's going to authenticate ourselves with the Twitter servers using our API Key and API Secret. 37
Now, at this stage, and previously, some of you guys might have wondered, "Well, if we have our API Keys inside 38
here and we upload our app to GitHub, 39
isn't that kind of dangerous? 40
And you're absolutely right. 41
Having API Keys, especially ones you have to pay for, 42
so, for example, currently on the Twitter app, this is using standard access, so we're not paying and we're 43
not giving any of our payment details so that international students who have issues using credit cards 44
in the US or don't actually have a credit card, then you know you can still learn along with all of the 45
lessons. 46
So I try to avoid using any services in my tutorial that requires a credit card sign up. 47
But at some point, you might need to use a higher access level tier, such as their Premium tier where 48
you can make more queries to their servers per minute, and you can get back more data from the Ywitter 49
servers as well. 50
So at that stage, then your API Key and your API Secret is directly linked to your credit card, 51
so that means that if somebody steals it and they use it in their app and they use up all of your credits, 52
then you're not going to be very happy. 53
So in those cases, you have to make sure that these API Keys are not uploaded to GitHub. 54
There are a lot of people who crawl through GitHub projects looking for these API Keys and using them, 55
especially things like AWS Keys, 56
it's very, very precious, and you have to make sure that you keep this secret. 57
Now, the simplest way of doing that is to simply create a new plist file by going to File, New, File, 58
and under the iOS tab, we create a new Property List file. 59
And the Secrets.plist can have your API Key, so this will be API Key, 60
and then you put in the String value, obviously, here, and then you add another one 61
that's the API Secret, 62
and then you add the string value here. 63
And as we described inside the GitHub module, you would add this Secrets.plist to the gitignore 64
plist so that it does not get uploaded to GitHub. 65
And this is probably one of the most frequently used ways for iOS developers to obfuscate their secrets 66
such as API Keys and API Secrets. 67
Now, some of you might be wondering, "Once my app is on the app store and somebody gets a hold of the actual 68
IPA file or the actual app software and they download it, and they try to butcher it, and they try to 69
dissect it, will they be able to find my API key? 70
Yes, that is--that is in fact the case. 71
And in the course resources list, I linked to a Stack Overflow, and so that's really quite exhaustive 72
on this topic. 73
In fact, you'll find that it's actually very, very difficult to keep your secure keys completely secure 74
if you have an iOS app just because people are able to download the app and you need the keys to be accessible 75
at the stage when the app is run. 76
So this is a good link to have a read about if you are really worried about this topic. 77
But in most cases, it's sufficient to simply use a Secrets.plist file and keep it off GitHub. 78
All right. 79
So now that we've got our Swifter Authentication setup, the next thing to do is to use Swifter and to search 80
for tweets on Twitter. 81
Now, unfortunately, if you have a look at the documentation for Swifter, it's not very exhaustive. 82
It tells you about how you get the Home Timeline and how you can getUser FollowerIDs, getListSubscribers, 83
but there's actually a lot more methods that it can do and they're not all listed over here. 84
So how can we figure out what it can do? 85
Well, if we go inside 86
viewDidLoad and we tap into our Swifter object and we hit dot. 87
Now, we can access all of the methods that are available and automatically suggested to us that Swifter 88
can perform. 89
So if we scroll through this list, you can see we've got addListMember, authorize, blockUser, 90
checkListMembership, createList, deleteList, destroyDirectMessages, favoriteTweet, followUser. And you can 91
see that these methods are pretty self-explanatory. 92
They're very well named and you should be able to understand exactly what it does 93
just by reading the method name which is always a good sign of good naming conventions, 94
right? 95
So remember that when your naming your own method to follow this kind of style where it should be really 96
obvious to anybody reading it even without any documentation what the method does. 97
Now, in our case, the method that we need--this is a very long list because we can use Swifter to do a 98
lot of things, such as get the IDs of the followers of the user, getUserSuggestions, listTweets, 99
lookupFriendships, loads and loads of things. But the one that we want is something called searchTweet. 100
So if we scroll down to this area around the "S" level, you can see that we've got searchTweet using a 101
String and giving a failure handler or we can have the really exhaustive one which is searchTweet using 102
loads of things. And that's the one that I'm going to choose. 103
So let's go ahead and hit enter to get it to automatically insert this gigantic method call. 104
Now, don't worry about how many parameters this method call has because we're not gonna be using many 105
of them and we'll get rid of some of the ones that we don't need. 106
Now, as you know from before, when you hold down the option key and your question mark comes up, when you 107
hover over, say, a method or an object. 108
So for the object, I can click on it and I can see what is its type or what is its class, essentially. 109
And for the methods, I can click on it and it gives me the Declaration, the Summary, as well as a Discussion, 110
and all of the Parameters that are available. 111
Now, this Discussion part actually comes from the Twitter APIs. 112
So if you have a look on the Twitter Developer docs, again, this is a link inside the Course Resources 113
list so that you can navigate to it easily. 114
You can see that there's a section called Standard Search API which is what we have access to by not 115
paying Twitter anything. 116
And here, you can see that there is a detailed reference of the Search API endpoints. 117
So let's head over there. And here is a whole bunch of information of, essentially, how this method works, 118
and this is where this part comes from. As you can see here, "Returns a collection of relevant Tweets matching 119
a specified query, "Returns a collection of relevant Tweets matching a specific query." 120
So this is the page that we're going to be referring to when we are using this particular Swifter method. 121
Now, if you look at all of these parameters and you're wondering what each of them do, then have no fear, 122
because they are all listed in a really neat table and they're all explained extensively about what 123
they are for, how you use it, what they are expecting. 124
So let's go through some of these options. 125
The only parameters that are required is the one that is using which is "searchTweet using:" 126
So this is your query String, right? 127
So if you wanted to search for tweets that were at Apple, then that's what you would put in here. 128
Effectively, you would replace the placeholder with a String 129
that's @Apple, 130
then you'll be searching for tweets that contain this handle. 131
So this is your search query. 132
And, of course, if you're going to search for tweets, this has to exist. 133
So this is obligatory. 134
The other two that you need to have in there is what to do when you get a successful response and what 135
to do when you get a failure response back from the Twitter service. You need to handle those. And all 136
of the rest of these other ones, 137
these other parameters, they're all optional. And you can see that because they list it in this table here. 138
You can see whether if it's required, this is column, and the search query is, of course, required. Geocode 139
is optional. Language is optional. Locale is optional. 140
All of these are optional, 141
other than this parameter using, which is the same as the q parameter over here, and the other one is 142
success and failure. 143
So let's go ahead and delete all of these other parameters and only keep what is strictly necessary. 144
Okay. 145
So next thing we need to handle is what to do when the search was successful and we get a successful 146
response from the Twitter servers. 147
Well, if you click on this particular placeholder, make it turn blue, and hit enter, and it automatically 148
insert our callback closure over here. 149
And these are the two objects that we're going to get back upon a successful query. And the first object 150
is the actual set of results of tweets. 151
And the second object is the metadata around our search. 152
So how long did the search take? 153
Was it successful, et cetera? 154
So we're gonna name these two JSONs, results and metadata. And then inside this part for the code 155
placeholder is where we're going to print out our results, just so that we can test it and see that everything's 156
working as expected. The next one is to handle the failure scenario. 157
So let's click on the Swifter FailureHandler and, again, hit enter to automatically insert the callback. 158
And the error, 159
we're just gonna call error. And inside the code placeholder, I'm going to delete that and, instead, replace 160
it with print and we're going to say, "There was an error with the Twitter API Request," 161
and then we're going to include that error in there. 162
So if there was an error with making a request to the Twitter servers, for example, if we had our consumerKey 163
wrong or we didn't include a consumerKey and consumerSecret, then our authentication would fail, and 164
we would get an error back from the Twitter servers saying something like, 4 or 3, not authenticated, and 165
we'll get this printed down here in our debug console, and we can use it to figure out what went wrong. 166
Now, if it was successful, however, we would be inside this area printing the results that we got back 167
that matches our particular search query, 168
so all the tweets that contain the handle at Apple. 169
So, now this is the very simplest way of searching for tweets through the Twitter API. 170
So let's give this a go and I'm just gonna go ahead and click Run so that when our View Controller, our 171
initial View Controller gets loaded up, then all of this code gets carried out, 172
and we should be able to see either a set of JSON results or a error in our debug console. 173
All right. 174
So there goes our app. 175
It currently doesn't do anything. But if we look in our debug console, you can see there's loads and loads 176
of information that came back. So we can presume that it was pretty successful because if there was an 177
error, it would be much shorter than this. 178
So let's go ahead and click in here and hit command A to select all, and then command C to copy all of 179
it. 180
And we're going to go on to a Chrome and we're going to find ourselves a JSON editor. So I'm gonna go 181
over to jsoneditoronline.org, and I'm going to paste everything that I had from my debug console. 182
Now, remember that there's a part of the debug console that has all of these messages from Xcode. And 183
this is, of course, not a part of the JSON. 184
And so we're going to delete all of those parts. And starting at that square bracket and ending at a 185
closing square bracket, should be everything that is our JSON. 186
So let's go ahead and click the right arrow to turn it into a format that is much more human readable. 187
And you can see that we've got an array of 15 items back from the Twitter server. 188
And if we check the first item, you can see it's got a whole bunch of properties such as the source. 189
So this is, what was the application that was used to make this tweet, 190
what was the date that it was created at, what was the location that it was created at, was it-- 191
was it favorited or not, 192
what was the text of the actual tweet, 193
how many times has it been retweeted, 194
what's the language it's in, 195
was it in reply, 196
and you can see there's like loads and loads of pieces of data that's associated with this single tweet. 197
But the part that we're interested in is actually just the text of the tweet because that's what we're 198
going to be using to perform sentiment analysis on. 199
So that's what we'll be trying to retrieve from our JSON once we get it up and running.