0
1
00:00:00,330 --> 00:00:00,720
All right.
1

2
00:00:00,750 --> 00:00:08,160
So now that we've gotten an in-depth understanding of Swift protocols and delegates, it's time to work
2

3
00:00:08,190 --> 00:00:16,590
on the heart of the problem of this Clima app which is to work with APIs, so that we can fetch live weather
3

4
00:00:16,590 --> 00:00:18,550
data from across the internet.
4

5
00:00:20,050 --> 00:00:23,020
Firstly, what is an API?
5

6
00:00:23,020 --> 00:00:31,090
Well, it stands for Application Programming Interface. And the official definition is that you can consider
6

7
00:00:31,090 --> 00:00:40,630
it as a set of commands functions, protocols, and objects. And APIs can be used to create software or to
7

8
00:00:40,660 --> 00:00:43,830
interact with an external system.
8

9
00:00:43,900 --> 00:00:49,990
And the beauty of an API is that it provides developers with standard commands for performing common
9

10
00:00:49,990 --> 00:00:54,050
operations so they don't have to write the code from scratch.
10

11
00:00:54,070 --> 00:01:02,050
Now, we've already been using APIs when we've been creating iOS apps, we've been using the APIs that
11

12
00:01:02,110 --> 00:01:03,700
Apple has created.
12

13
00:01:03,850 --> 00:01:08,430
And these are types of APIs that you would use to create software,
13

14
00:01:08,500 --> 00:01:08,770
right?
14

15
00:01:09,070 --> 00:01:15,520
So whenever we went to the docs, we've been getting hold of the API reference. And when we're working
15

16
00:01:15,520 --> 00:01:22,570
with these classes that Apple has created, for example, the AVAudioPlayer, then these are the standard
16

17
00:01:22,570 --> 00:01:29,470
commands for performing common operations, such as playing a sound.
17

18
00:01:29,480 --> 00:01:33,630
Now, in addition to the API that are used to create software,
18

19
00:01:33,770 --> 00:01:38,910
there are also APIs which are used to interact with an external system.
19

20
00:01:39,440 --> 00:01:45,620
So, for example, if you've ever seen in the Tinder app where they have this section called Shared Friends
20

21
00:01:45,620 --> 00:01:49,370
or Shared Interests, where do they get this data from.
21

22
00:01:49,370 --> 00:01:57,080
Well, when you log into Tinder using your Facebook account, Tinder actually ask Facebook for this data
22

23
00:01:57,350 --> 00:02:00,300
so that they can populate it into their app.
23

24
00:02:00,530 --> 00:02:06,470
So effectively, you can consider an API as simply just a contract.
24

25
00:02:06,470 --> 00:02:12,500
It's the contract between the developer and the API provider.
25

26
00:02:12,500 --> 00:02:19,250
So for example, when we're building our weather app, because we need to populate our app with live weather
26

27
00:02:19,250 --> 00:02:27,050
data for all locations across the world, we're going to be using OpenWeather Maps API that they provide.
27

28
00:02:27,170 --> 00:02:34,940
And in this case, by using the API, we're effectively entering in a contract where we say that we'll use
28

29
00:02:35,240 --> 00:02:43,040
the methods that you provide and we'll abide by the rules that you set out in your API docs. And in return,
29

30
00:02:43,100 --> 00:02:49,370
you'll promise to keep all of your requirements the same so that our app doesn't crash because you've
30

31
00:02:49,370 --> 00:02:50,480
changed something.
31

32
00:02:51,050 --> 00:02:59,480
So in this case, we have our app and we have the API provider. And what our app is going to do is it's
32

33
00:02:59,480 --> 00:03:01,310
going to use the API.
33

34
00:03:01,310 --> 00:03:09,020
And when the user types in a city name in our app, we're going to pass that city name to OpenWeather
34

35
00:03:09,470 --> 00:03:17,420
using the API that they have set out for formatting this request, and then OpenWeather in response is
35

36
00:03:17,420 --> 00:03:23,600
going to send us the live weather data, so that we can use it in our app.
36

37
00:03:23,600 --> 00:03:31,640
So if you head over to openweathermap.org/api, you can take a look at the documentation for
37

38
00:03:31,640 --> 00:03:33,960
the API that they provide.
38

39
00:03:33,960 --> 00:03:40,520
So you can get things such as the current weather data, the hourly forecast, the 16 day / daily forecast,
39

40
00:03:40,910 --> 00:03:44,050
and a whole bunch of other things as well.
40

41
00:03:44,210 --> 00:03:50,810
Now, because they are responsible for hosting the data, keeping it updated, they have to make sure that
41

42
00:03:50,810 --> 00:03:53,360
people don't abuse this service.
42

43
00:03:53,360 --> 00:04:03,350
So very often these open APIs will ask you to sign up for an API key, and that key is going to uniquely
43

44
00:04:03,440 --> 00:04:06,590
identify you as a developer.
44

45
00:04:06,590 --> 00:04:12,290
So the first thing that we need to do to work with the API is if it requires an API key, such as 
45

46
00:04:12,290 --> 00:04:18,790
OpenWeather Map, then we have to sign up. And it's completely free and they don't need any credit card details.
46

47
00:04:19,040 --> 00:04:26,360
They just want you to create a new account there. Once you signed up, then you should be able to see a
47

48
00:04:26,360 --> 00:04:34,100
page that looks like this. And you should head over to this section called API keys. And here you should
48

49
00:04:34,100 --> 00:04:42,000
be able to see your custom API key that will allow you to use this API service.
49

50
00:04:42,240 --> 00:04:47,530
Go ahead and copy your API key and keep it somewhere safe.
50

51
00:04:47,640 --> 00:04:54,930
And now we're going to see how we can use this API service. So the data that I want is the current weather
51

52
00:04:54,930 --> 00:04:55,470
data.
52

53
00:04:55,860 --> 00:05:00,930
So I'm going to go ahead and click here to take a look at the documentation.
53

54
00:05:00,930 --> 00:05:07,920
You can see that you can get the current weather data for a location by the city name, by the city ID,
54

55
00:05:07,950 --> 00:05:13,740
by geographic coordinates with latitude and longitude, by ZIP code, and a whole bunch of other things
55

56
00:05:13,740 --> 00:05:15,240
that you can read about.
56

57
00:05:15,690 --> 00:05:20,860
Now, in our case, we want to get the weather for a particular city name.
57

58
00:05:21,090 --> 00:05:31,040
So if we go ahead and take a look at their example API calls, you can see that the city name comes after
58

59
00:05:31,100 --> 00:05:39,110
this parameter called queue, and then you also have to supply what's called an app ID, and this is your
59

60
00:05:39,230 --> 00:05:41,960
API key that we got just now.
60

61
00:05:42,050 --> 00:05:48,380
So let's try and structure this API call using our own API key.
61

62
00:05:49,070 --> 00:05:54,050
So first things first, let's go ahead and copy this API call.
62

63
00:05:54,440 --> 00:06:03,050
So it's api.openweathermap.org/data/2.5/weather, and then we have a question
63

64
00:06:03,050 --> 00:06:03,680
mark,
64

65
00:06:03,740 --> 00:06:07,890
and the question mark denotes the beginning of the queries.
65

66
00:06:07,910 --> 00:06:11,610
So these are the queries that you're sending to open weather map.
66

67
00:06:11,810 --> 00:06:15,270
And it's a bit like the inputs to our Swift functions.
67

68
00:06:15,470 --> 00:06:19,310
We have to have a name or a parameter name.
68

69
00:06:19,310 --> 00:06:22,670
So in this case "q" denotes the city name.
69

70
00:06:22,910 --> 00:06:27,800
And then we have an equal sign and then we pass in the name of the city that we want to check the weather
70

71
00:06:27,800 --> 00:06:29,020
for.
71

72
00:06:29,030 --> 00:06:38,120
So let's go ahead and copy this and we're going to paste it into our browser. And I'm going to delete
72

73
00:06:38,150 --> 00:06:43,700
the part where it says city name in brackets because I'm actually going to put the actual name of the
73

74
00:06:43,700 --> 00:06:45,440
city that I'm interested in.
74

75
00:06:45,440 --> 00:06:52,020
So London. Now that I've got my query as London, if I go ahead and hit enter,
75

76
00:06:52,050 --> 00:07:00,670
you'll see I get an error. And it says, "Invalid API key. Please see this address for more information."
76

77
00:07:00,690 --> 00:07:09,300
So once we take a look at this address, you'll see that the problem is because I haven't added in my
77

78
00:07:09,420 --> 00:07:12,260
API key. So I've registered it,
78

79
00:07:12,300 --> 00:07:21,500
I've copied it, but I now have to put it into my query. Ss you can see in the sample query,
79

80
00:07:21,620 --> 00:07:28,700
there is a parameter name called "appid," and after the equals sign, you have to put in your app ID
80

81
00:07:28,730 --> 00:07:33,140
that you got by registering with OpenWeather Map.
81

82
00:07:33,140 --> 00:07:40,310
Let's head over to our URL and let's start off our list of parameters or inputs with the question
82

83
00:07:40,310 --> 00:07:41,040
mark,
83

84
00:07:41,300 --> 00:07:48,380
and then let's add the name of the parameter which is appid all in lowercase, and then equal sign, and then
84

85
00:07:48,380 --> 00:07:56,780
we're going to paste in the appid that we got from OpenWeather Map under the API key section. And
85

86
00:07:56,780 --> 00:08:02,320
then after that, we're going to tag on another parameter or another input.
86

87
00:08:02,420 --> 00:08:09,980
So we're going to use the ampersand to signify that we're done with this app ID parameter input and
87

88
00:08:09,980 --> 00:08:16,740
we're now going to add the "q" parameter which is going to denote the city name. And after the equals sign,
88

89
00:08:16,760 --> 00:08:22,370
I'm going to put in the name the city that I'm interested in which is London.
89

90
00:08:22,370 --> 00:08:28,850
And now if I hit enter, you'll see that I'm getting live data as of this moment right now,
90

91
00:08:28,850 --> 00:08:32,330
what is the weather in London. So cloudy,
91

92
00:08:32,330 --> 00:08:40,810
as usual. Now, if you're not getting this data back, it might be because your app ID or your API key
92

93
00:08:41,110 --> 00:08:43,500
hasn't yet been activated.
93

94
00:08:43,570 --> 00:08:47,110
It usually takes them a couple of hours to do this.
94

95
00:08:47,110 --> 00:08:50,770
So it might be worth coming back and trying it the next day.
95

96
00:08:50,770 --> 00:08:57,220
But for me, it often takes about five to ten minutes before they actually activate my key so it might
96

97
00:08:57,220 --> 00:09:01,220
be worth getting a cup of tea and coming back to try it again later.
97

98
00:09:01,270 --> 00:09:08,110
Now, the second thing you might be wondering is when you're seeing this data come back, you probably won't
98

99
00:09:08,110 --> 00:09:14,100
be seeing it in this pretty sort of tree structure instead.
99

100
00:09:14,160 --> 00:09:19,470
You'd probably be looking at the data that's coming back that looks like this.
100

101
00:09:19,830 --> 00:09:25,410
Now, in order to get it turn into a tree structure which is much easier for us to be able to see and
101

102
00:09:25,410 --> 00:09:32,940
understand as humans, then I recommend getting this free Chrome extension called JSON View Awesome.
102

103
00:09:33,090 --> 00:09:38,730
And once you install it and activate it, then it will automatically detect when you're getting JSON
103

104
00:09:38,820 --> 00:09:44,650
formatted data and it will formatted correctly for you.
104

105
00:09:44,860 --> 00:09:53,140
So now that we've seen that we can structure our API call by adding our different parameters after the
105

106
00:09:53,140 --> 00:10:02,530
URL separated by ampersands, and with the sort of key value kind of format where we have the name of
106

107
00:10:02,530 --> 00:10:09,450
the parameter, an equal sign, and the value that we're sending over to the API provider.
107

108
00:10:10,300 --> 00:10:16,840
So as a challenge, I want you to take a look at the API docs for getting the current weather data. Because
108

109
00:10:16,840 --> 00:10:24,290
you might notice that in the data that we're getting back, the temperature for London is 
109

110
00:10:24,290 --> 00:10:25,930
293.
110

111
00:10:25,990 --> 00:10:30,240
So don't worry, I'm not actually burning right now.
111

112
00:10:30,280 --> 00:10:38,650
This is not the temperature in Celsius or Fahrenheit, it's actually in Kelvins which is the scientific
112

113
00:10:38,650 --> 00:10:46,420
unit of measure for temperature. In order to convert it into a number that we actually can understand,
113

114
00:10:46,420 --> 00:10:55,690
OpenWeather Map provides a parameter called units and you can set it to be imperial or metric.
114

115
00:10:55,690 --> 00:11:03,970
So go ahead and update your URL, your API call, so that you have the temperature getting back in either
115

116
00:11:03,970 --> 00:11:10,870
metric, Celsius, or imperial, which is Fahrenheit, depending on whichever one you find easier to understand.
116

117
00:11:14,510 --> 00:11:14,860
All right.
117

118
00:11:14,930 --> 00:11:21,260
So all we have to do to tag on another parameter is to add another ampersand.
118

119
00:11:21,260 --> 00:11:24,650
And in this case, the name of the parameter is units.
119

120
00:11:24,680 --> 00:11:30,980
And remember that when you're adding these parameter names because this is effectively our contract,
120

121
00:11:31,100 --> 00:11:37,370
the API that we're using to get data from OpenWeather Map, you have to make sure that you're spelling
121

122
00:11:37,370 --> 00:11:40,250
it exactly the way that is prescribed by them.
122

123
00:11:40,760 --> 00:11:42,620
Otherwise, they won't know what you're talking about.
123

124
00:11:43,310 --> 00:11:46,390
So the units, in my case, is going to be equal to metric.
124

125
00:11:46,460 --> 00:11:48,620
I can understand Fahrenheit.
125

126
00:11:49,130 --> 00:11:55,730
But now once I put that in, I can see that in London, it's about 9.9 seven degrees,
126

127
00:11:56,000 --> 00:12:03,600
and that feels just about right. At the moment, we're making this request through our browser.
127

128
00:12:03,740 --> 00:12:08,580
How can we do the same thing but from our app?
128

129
00:12:08,870 --> 00:12:10,880
Well, let's get back to our project.
129

130
00:12:10,940 --> 00:12:18,730
And in the model folder, I'm going to create a new file which I'm going to call the WeatherManager.
130

131
00:12:18,860 --> 00:12:28,510
So it's going to be a new Swift file and I'm going to name the file WeatherManager. And inside this
131

132
00:12:28,600 --> 00:12:29,740
brand new file,
132

133
00:12:29,740 --> 00:12:37,680
we're going to create a struct which is called WeatherManager. And one of the first properties we're
133

134
00:12:37,680 --> 00:12:43,480
going to create in our WeatherManager is going to be the weatherURL.
134

135
00:12:44,400 --> 00:12:51,810
And in my case, I'm simply going to copy exactly what I have in my browser at the moment and I'm going
135

136
00:12:51,810 --> 00:12:55,730
to paste it in here as a string.
136

137
00:12:55,740 --> 00:13:03,420
Now, the part of this URL that is going to change is going to be this London input because I'm
137

138
00:13:03,420 --> 00:13:08,560
going to use different cities depending on whatever the user typed in.
138

139
00:13:08,610 --> 00:13:15,730
So notice how you can actually arrange each of these parameters in the URL in any order you like.
139

140
00:13:15,750 --> 00:13:22,620
You can have units equals metric, then q equals London, that works, or you could even have the appid
140

141
00:13:22,650 --> 00:13:25,620
right at the end, like so,
141

142
00:13:25,770 --> 00:13:27,060
and it would work.
142

143
00:13:27,060 --> 00:13:33,480
It doesn't actually care about the order. It looks for the keys and gets the values.
143

144
00:13:33,480 --> 00:13:42,000
So in our case, I'm actually going to get rid of this and "&a=london" because I'm going to add that
144

145
00:13:42,300 --> 00:13:51,030
programmatically a little bit later on using what the user typed into the UITextField. So I can create
145

146
00:13:51,120 --> 00:14:00,750
a method in my WeatherManager called fetchWeather, and this takes an input which is going to be the
146

147
00:14:00,990 --> 00:14:02,120
cityName.
147

148
00:14:02,490 --> 00:14:10,400
And that's, of course, going to be a string data type. And then inside this method, I'm going to create
148

149
00:14:10,460 --> 00:14:20,150
the URL string and it's going to be a combination of the base string which is the weatherURL
149

150
00:14:20,300 --> 00:14:32,270
we've got up here. And then at the very end, I'm going to tag on another ampersand, the "q," which is
150

151
00:14:32,270 --> 00:14:34,870
the parameter name, the equal sign,
151

152
00:14:35,120 --> 00:14:44,080
and then in the string interpolation, I'm going to insert the cityName. So now I should be able to go
152

153
00:14:44,080 --> 00:14:56,200
into my WeatherViewController and create a new weatherManager, and set it equal to a new WeatherManager struct,
153

154
00:14:56,200 --> 00:15:02,370
and initialize it with a set of parentheses.
154

155
00:15:02,830 --> 00:15:12,130
And when my textFieldDidEndEditing and before I reset the FextFields.text, I'm going to use the
155

156
00:15:12,130 --> 00:15:21,330
text in the text field. So I'm going to write let city = searchTextField.text.
156

157
00:15:22,630 --> 00:15:31,930
And because this property is an optional and I want to actually pass over to my WeatherManager a definite
157

158
00:15:31,930 --> 00:15:40,870
string, instead of an optional string, I'm going to use an "if let" to optionally unwrap 
158

159
00:15:40,870 --> 00:15:42,340
my searchTextField.text property.
159

160
00:15:42,970 --> 00:15:52,960
So now my city property is a proper string and I can use it when I call where the weatherManger.fetchWeather
160

161
00:15:52,960 --> 00:15:59,690
and the cityName is this city that the user has entered.
161

162
00:15:59,890 --> 00:16:06,160
So now if you want to assure yourself that everything is working, you can actually create a print statement
162

163
00:16:06,490 --> 00:16:09,970
that prints out the URL string. And when you run the app
163

164
00:16:12,980 --> 00:16:21,820
and you type in a city name and hit either the search button or the go button, you should see the final
164

165
00:16:21,840 --> 00:16:29,340
URL that's been formatted together. So you see this entire weatherURL up to here, 
165

166
00:16:29,350 --> 00:16:29,970
metric,
166

167
00:16:30,140 --> 00:16:39,740
and then we tag on the "&q=Paris" And just as a safety check, we can copy this and paste it into
167

168
00:16:39,830 --> 00:16:44,460
our browser and check to make sure that it actually works.
168

169
00:16:44,480 --> 00:16:52,280
Now, all that's left to do is to go across the internet from our app and fetch the actual data back.
169

170
00:16:52,280 --> 00:16:57,220
And that is something called networking which is what we're going to talk about in the next lesson.
170

171
00:16:57,260 --> 00:16:58,220
So I'll see you there.
