0
1
00:00:00,480 --> 00:00:05,160
In this lesson, we're going to be learning how to parse the response that we're getting back from 
1

2
00:00:05,160 --> 00:00:07,530
OpenWeather Map's servers.
2

3
00:00:07,680 --> 00:00:15,090
So now that you've seen how closures work, let's convert our completion handler here to an actual Swift
3

4
00:00:15,090 --> 00:00:16,740
closure.
4

5
00:00:16,740 --> 00:00:24,120
Instead of creating session.dataTask with URL and passing in the completionHandler as a
5

6
00:00:24,180 --> 00:00:30,930
actual method, I'm going to go ahead and initialize this dataTask again, because I'm going to borrow
6

7
00:00:31,020 --> 00:00:33,660
Xcode's code completion to help me.
7

8
00:00:33,750 --> 00:00:39,270
So I'm going to choose the one where I give it a URL and I end up with a completionHandler that
8

9
00:00:39,270 --> 00:00:39,820
triggers
9

10
00:00:39,840 --> 00:00:46,230
once it's done with the task. And the URL is, again, going to be just the URL that we got from
10

11
00:00:46,440 --> 00:00:47,930
our optional binding.
11

12
00:00:48,090 --> 00:00:56,100
But here in the completionHandler, where you see this gray area, which is the code placeholder that
12

13
00:00:56,430 --> 00:00:58,910
is telling us what it's expecting.
13

14
00:00:59,130 --> 00:01:03,690
If you go ahead and select it, so turn it blue, and then hit enter,
14

15
00:01:03,690 --> 00:01:08,430
it should format it into a trailing closure automatically for you.
15

16
00:01:09,180 --> 00:01:16,230
So now that we see this familiar closure format, we can go ahead and add in the names of the inputs.
16

17
00:01:16,290 --> 00:01:19,780
So that's going to be called data, that's going to be called response,
17

18
00:01:19,860 --> 00:01:22,410
and that's going to be called error.
18

19
00:01:22,410 --> 00:01:30,170
And now inside this code block, we're going to move in everything that used to live in our handle method,
19

20
00:01:30,540 --> 00:01:37,470
and it's now going to go inside our closure. And we can delete the separate method. And then I'm going
20

21
00:01:37,470 --> 00:01:45,780
to select everything and hit control I, or whatever your shortcut might be if you go to Editor, Structure
21

22
00:01:45,840 --> 00:01:47,110
and Re-indent.
22

23
00:01:47,110 --> 00:01:48,450
So this is what I see.
23

24
00:01:48,450 --> 00:01:50,020
You might have something different.
24

25
00:01:50,250 --> 00:01:57,440
And now I've reformatted my code to look a lot more Swifty with my anonymous function here.
25

26
00:01:57,690 --> 00:02:05,850
And I've got my trailing closure which is going to carry out this task once it completes with the
26

27
00:02:05,850 --> 00:02:07,430
dataTask.
27

28
00:02:07,900 --> 00:02:14,470
So now that we're done with getting hold of the data, we don't really want it as a dataString because
28

29
00:02:14,860 --> 00:02:20,830
this is impossible to read even if I concentrate and really squint my eyes.
29

30
00:02:20,830 --> 00:02:30,160
Instead, we're going to pass this piece of data and turn it into an actual Swift object with properties
30

31
00:02:30,190 --> 00:02:32,170
and methods.
31

32
00:02:32,170 --> 00:02:41,320
So to pass this data which is currently in a JSON format and I know it's a JSON response because when
32

33
00:02:41,320 --> 00:02:47,890
I look at the documentation, you can see that the example of an API response in the JSON format looks
33

34
00:02:47,890 --> 00:02:49,990
exactly like what we've got.
34

35
00:02:49,990 --> 00:02:57,430
And JSON formatted data that's being transported across the internet, is probably one of the most popular
35

36
00:02:57,520 --> 00:03:05,860
and one of the most widely used formats. And other formats like XML is fast going out of fashion.
36

37
00:03:05,980 --> 00:03:08,920
But what exactly is a JSON?
37

38
00:03:08,920 --> 00:03:11,110
What does it actually stand for?
38

39
00:03:11,110 --> 00:03:15,940
Well, a JSON stands for JavaScript Object Notation.
39

40
00:03:15,940 --> 00:03:21,670
This actually comes from the JavaScript world, the web world, where there's a lot of data being transported
40

41
00:03:22,000 --> 00:03:29,610
across the internet, and they need to make it as efficient, as lightweight, and as small as possible.
41

42
00:03:29,710 --> 00:03:37,490
I want you to imagine that you start out with a wardrobe and this wardrobe happens to be an object that's
42

43
00:03:37,510 --> 00:03:39,520
created in JavaScript.
43

44
00:03:39,520 --> 00:03:46,370
So this is where a JavaScript object would look like. And that created kind of almost like our dictionaries.
44

45
00:03:46,420 --> 00:03:48,910
But in this case, the object is called wardrobe.
45

46
00:03:48,910 --> 00:03:54,310
It has a property called doors which is set to equal to a property called drawers and a property called
46

47
00:03:54,310 --> 00:04:00,890
color. When this is being transported across the internet in order to save space,
47

48
00:04:00,910 --> 00:04:06,510
we're going to get rid of all this formatting which doesn't really matter while it's in transit anyways.
48

49
00:04:07,210 --> 00:04:16,140
And we're going to turn it into a flat pack wardrobe like the ones you get from IKEA. The flat pack wardrobe
49

50
00:04:16,150 --> 00:04:23,590
still retains all of the most important parts of the data, namely the syntax, the properties separated
50

51
00:04:23,590 --> 00:04:33,490
by commas, and each object encased in a set of curly braces. But it gets turned into a string, rather than
51

52
00:04:33,550 --> 00:04:40,990
an actual object. But once it arrives on the other side, once you've gotten it delivered from IKEA and 
52

53
00:04:40,990 --> 00:04:46,720
you've managed to find all the screws which are impossible to find, and you've built your wardrobe back
53

54
00:04:46,720 --> 00:04:55,030
up again, then you still have a living, breathing, large wardrobe. But during transit, it was turned into
54

55
00:04:55,090 --> 00:04:59,360
a much smaller format so that it can be transported easily.
55

56
00:04:59,500 --> 00:05:06,030
Now, in our case, we don't actually want to unpack the JSON into a JavaScript object.
56

57
00:05:06,190 --> 00:05:10,790
What we want is a Swift object to come out of it.
57

58
00:05:10,870 --> 00:05:17,890
So we would initialize our Swift object with either a struct or a class constructor with properties
58

59
00:05:17,980 --> 00:05:20,290
like doors, drawers, and colour.
59

60
00:05:20,320 --> 00:05:23,040
So let's see how we can do this.
60

61
00:05:23,410 --> 00:05:29,890
So I'm gonna go ahead and delete my comments, just so that it's easier for you to see what's going on.
61

62
00:05:29,890 --> 00:05:35,380
Feel free to keep your comments or any additional things that you have in your code if you wish.
62

63
00:05:35,380 --> 00:05:39,740
But I just want to tidy up the code a little bit so you can see more at a glance.
63

64
00:05:39,820 --> 00:05:46,630
So down here below performRequest, I'm going to create another method which is going to be called
64

65
00:05:47,110 --> 00:05:48,040
parseJSON.
65

66
00:05:48,160 --> 00:05:55,180
And this is going to take a single input which is going to be the weatherData and this is, of course,
66

67
00:05:55,180 --> 00:06:01,990
going to be the format of data which is the format that we get back from our dataTask.
67

68
00:06:02,380 --> 00:06:10,570
So then we should be able to call our parseJSON method here and pass over this unwrapped safeData
68

69
00:06:11,140 --> 00:06:14,830
which meets the requirements of being a data object.
69

70
00:06:15,490 --> 00:06:21,690
But notice how we're getting a error here telling us that call to method
70

71
00:06:21,770 --> 00:06:28,040
'parseJSON' inside a closure requires an explicit 'self.'
71

72
00:06:28,060 --> 00:06:35,890
Normally, when we call methods such as when we called performRequest, we didn't actually need to say
72

73
00:06:36,160 --> 00:06:45,880
who was the object that owned this method performRequest to call this method. And in fact, the full way
73

74
00:06:45,940 --> 00:06:48,570
of writing this code would have been 'self.'
74

75
00:06:48,610 --> 00:06:57,130
So call the method performRequest from this current structure which is here. Now, the reason why we didn't
75

76
00:06:57,130 --> 00:07:03,460
have to do it is because Swift is actually doing it for us under the hood, and this keeps our code nice
76

77
00:07:03,460 --> 00:07:09,580
and tidy, and we already can see that performRequest is right there inside our WeatherManager,
77

78
00:07:09,580 --> 00:07:12,380
so it is superfluous to add the 'self'
78

79
00:07:12,400 --> 00:07:13,030
in this case.
79

80
00:07:13,630 --> 00:07:21,940
But when we are inside a closure, then it can get confused about where to add the"self" and where to not
80

81
00:07:21,970 --> 00:07:28,900
add the "self," and where the method you're calling exists. Because remember our data task is triggering
81

82
00:07:28,900 --> 00:07:34,570
this method and when it gets triggered, then everything inside gets executed.
82

83
00:07:34,630 --> 00:07:43,990
So inside the closure, the rule is we must add the word "self" if we are calling a method from the current
83

84
00:07:43,990 --> 00:07:46,390
class which we are right here.
84

85
00:07:47,200 --> 00:07:49,420
So that fixes that error.
85

86
00:07:49,420 --> 00:08:00,030
And now we can focus on our parseJSON method. In order to parse our data from a JSON format,
86

87
00:08:00,150 --> 00:08:08,400
we first have to inform our compiler how the data is structured. And we can do that through the use of
87

88
00:08:08,490 --> 00:08:10,650
a structure that we create.
88

89
00:08:10,650 --> 00:08:17,640
So in the Model folder, again, I'm gonna create another file which is a Swift File, and I'm gonna call
89

90
00:08:17,640 --> 00:08:26,550
this the WeatherData because inside this file, I'm going to create the structure that's the WeatherData
90

91
00:08:26,550 --> 00:08:29,880
is going to come back in.
91

92
00:08:29,880 --> 00:08:37,870
Notice how if we have our data formatted with JSON Awesome, you can see it as a tree structure.
92

93
00:08:38,250 --> 00:08:46,140
So we're getting back an object that has 13 properties. And the first one is a property called coordinate
93

94
00:08:46,500 --> 00:08:53,580
which inside is another object that has a longitude and latitude properties. And we also have a property
94

95
00:08:53,580 --> 00:08:59,380
called a weather which inside actually has an array with a single item.
95

96
00:08:59,430 --> 00:09:05,820
So we have to basically break down this structure for the compiler to be able to chew through the data
96

97
00:09:05,850 --> 00:09:12,480
that it's getting in this format, and then we can assign property names, and we can turn it into a Swift
97

98
00:09:12,570 --> 00:09:13,650
object.
98

99
00:09:13,650 --> 00:09:19,170
So let's start with something quite simple, something that's just got a key and value pair.
99

100
00:09:19,170 --> 00:09:27,650
So for example, our name here. The property name is called name and the value is Paris.
100

101
00:09:27,740 --> 00:09:36,320
In this case, we could create our structure WeatherData and it can have a single property code name.
101

102
00:09:36,950 --> 00:09:37,900
And the name
102

103
00:09:37,910 --> 00:09:42,470
if we check is, of course, a string because it's got the quotation marks around it.
103

104
00:09:42,650 --> 00:09:43,480
So we'll sign it,
104

105
00:09:43,490 --> 00:09:45,750
the date type of a string.
105

106
00:09:45,950 --> 00:09:48,890
But this is not quite enough.
106

107
00:09:48,890 --> 00:09:58,130
In addition, we also have to say that our struct conforms to the Decodable protocol and that means
107

108
00:09:58,130 --> 00:10:06,080
that the WeatherData turned into a type that can decode itself from an external representation namely
108

109
00:10:06,350 --> 00:10:14,750
the JSON representation. Now that our WeatherData is Decodable and it's got a property called name,
109

110
00:10:14,950 --> 00:10:21,920
we can go back into our parseJSON method and create a decoder.
110

111
00:10:21,940 --> 00:10:27,530
And we're going to create that from the JSON decoder object,
111

112
00:10:27,580 --> 00:10:33,730
so this is an object that can decode JSON. And we're going to just initialize it.
112

113
00:10:33,850 --> 00:10:39,220
Next, we're going to use our decoder and we're going to decode.
113

114
00:10:39,250 --> 00:10:41,920
Now, this takes two inputs.
114

115
00:10:41,920 --> 00:10:48,700
Firstly, the data that you want to decode and a Decodable type.
115

116
00:10:48,700 --> 00:10:55,020
So a data type that we're using to decode that conforms to the decoder protocol.
116

117
00:10:55,030 --> 00:10:57,860
Well, we've got one of those right here.
117

118
00:10:57,920 --> 00:11:01,380
Our WeatherData is a Decodable type.
118

119
00:11:01,690 --> 00:11:09,810
So notice how in this case, it's expecting a type in here as the input, not an object.
119

120
00:11:09,910 --> 00:11:20,500
So to specify the weatherData type, rather than just the weatherData object, we have to add a ".self"
120

121
00:11:20,860 --> 00:11:22,930
to reference the type.
121

122
00:11:22,930 --> 00:11:31,820
So if I click on this fix button, it turns my WeatherData into a data type that I'm passing in.
122

123
00:11:32,230 --> 00:11:39,460
Now, finally, the data that we want to encode is going to be passed in as the last input and that is going
123

124
00:11:39,460 --> 00:11:42,260
to come from this weatherData right here.
124

125
00:11:42,280 --> 00:11:45,550
So that's what I'm going to put there.
125

126
00:11:45,580 --> 00:11:52,330
So, now we should have decoded our data. But we're still getting errors because it's telling us that this
126

127
00:11:52,450 --> 00:12:00,780
call to decode can throw but is not marked with a 'try' and the error is not handled.
127

128
00:12:00,820 --> 00:12:01,570
What does that mean?
128

129
00:12:01,750 --> 00:12:08,500
Well, if we take a look at this decode method again, you can see that it's marked with this "throws" keyword
129

130
00:12:08,980 --> 00:12:14,590
which means that if something goes wrong, it can throw out an error.
130

131
00:12:14,680 --> 00:12:19,310
And so instead of simply just calling it as we would with other methods,
131

132
00:12:19,510 --> 00:12:24,310
all we have to do is we have to market with a "try" keyword.
132

133
00:12:24,610 --> 00:12:29,650
And in addition, we should really wrap it inside a block.
133

134
00:12:29,680 --> 00:12:30,940
That's called a "do" block.
134

135
00:12:30,950 --> 00:12:40,150
So the "do" block has the thing with the "try," and that marks the method which can throw an error.
135

136
00:12:40,690 --> 00:12:45,990
But if it does throw an error, we have a catch block that can catch the error.
136

137
00:12:46,060 --> 00:12:56,120
So we could simply print the error in here. So now our error goes away and Xcode is now happy with the
137

138
00:12:56,120 --> 00:12:59,330
way that we're programming our project.
138

139
00:12:59,330 --> 00:13:04,660
The final thing we have to do is that decode actually has an output,
139

140
00:13:04,820 --> 00:13:10,260
so it's going to create a WeatherData object.
140

141
00:13:10,370 --> 00:13:17,150
Let's go ahead and capture that in a constant. We'll call it decoded data and we'll set it to the output
141

142
00:13:17,360 --> 00:13:19,250
of this method call.
142

143
00:13:19,580 --> 00:13:27,800
And then there's decoded data because it has the data type of our WeatherData which means that it has
143

144
00:13:27,800 --> 00:13:29,560
the property name.
144

145
00:13:29,930 --> 00:13:36,830
Well, then we can actually print out decodedData.name.
145

146
00:13:36,830 --> 00:13:38,780
Now, let's go ahead and run our app.
146

147
00:13:42,840 --> 00:13:52,050
And if I go ahead and type in the name of a city, say, "Belgrade," and hit enter, you can see that the name
147

148
00:13:52,050 --> 00:13:58,930
of the city is being printed, but it's not being printed from my WeatherViewController.
148

149
00:13:58,990 --> 00:14:03,450
There is no print statements in my text field delegate methods.
149

150
00:14:03,450 --> 00:14:09,250
In fact, the only one that's being triggered is this decodedData.name.
150

151
00:14:09,390 --> 00:14:14,850
So some of you might be thinking, well, you could be cheating," that might still be somehow coming from
151

152
00:14:14,880 --> 00:14:16,230
the text field.
152

153
00:14:16,230 --> 00:14:21,890
Show me a piece of data that comes from the API that we didn't enter into the app ourselves.
153

154
00:14:22,790 --> 00:14:23,350
Okay.
154

155
00:14:23,370 --> 00:14:25,720
So I'm always up for a challenge.
155

156
00:14:25,800 --> 00:14:29,770
So if we take a look at our result that we get back,
156

157
00:14:29,940 --> 00:14:34,510
notice how we're getting the temperature of the location back as well.
157

158
00:14:34,530 --> 00:14:36,790
Let's try and get hold of the temperature.
158

159
00:14:36,990 --> 00:14:44,460
Now, a really handy thing that the JSON Awesome plugin can do is when you select one of these properties
159

160
00:14:44,490 --> 00:14:51,030
by clicking on it, you can click on this green button that comes up and copy the path that it would take
160

161
00:14:51,120 --> 00:14:53,780
to reach this value.
161

162
00:14:53,790 --> 00:15:01,230
So, now inside here instead of decodedData.name, I'm going to delete the name and I'm going to paste
162

163
00:15:01,560 --> 00:15:03,270
what I copied over from JSON
163

164
00:15:03,270 --> 00:15:04,240
Awesome.
164

165
00:15:04,320 --> 00:15:12,160
So it's telling me that in order to get to the temperature, I have to take the entire piece of data,
165

166
00:15:12,160 --> 00:15:20,050
go to the main property, and in the main property, go to the property temp in order to get that temperature.
166

167
00:15:20,590 --> 00:15:23,800
And that is what the entire path would look like.
167

168
00:15:24,340 --> 00:15:29,710
But right now, we haven't defined these properties in all WeatherData.
168

169
00:15:29,770 --> 00:15:31,120
So let's go ahead and do that
169

170
00:15:31,120 --> 00:15:33,250
to make these errors go away.
170

171
00:15:33,850 --> 00:15:41,920
Firstly, we've got the top level which comes from our WeatherData and the top level property name is
171

172
00:15:41,920 --> 00:15:43,230
called "main."
172

173
00:15:43,420 --> 00:15:46,330
So that's going to be what we'll add in here.
173

174
00:15:46,330 --> 00:15:47,060
Main.
174

175
00:15:47,200 --> 00:15:49,540
But what data type is it going to have?
175

176
00:15:49,540 --> 00:15:58,030
Well, it's actually a object with five items, and that object has these properties: temp, pressure, humidity,
176

177
00:15:58,090 --> 00:15:59,110
et cetera.
177

178
00:15:59,260 --> 00:16:05,400
That means we actually need another struct which I'm just going to call Main.
178

179
00:16:05,770 --> 00:16:08,990
And this, again, has to be Decodedable.
179

180
00:16:09,250 --> 00:16:14,000
And then, this main is the one that's going to have that property temp.
180

181
00:16:14,680 --> 00:16:19,570
And remember that when you're creating these properties, it's a little bit different from how we would
181

182
00:16:19,570 --> 00:16:20,080
do it
182

183
00:16:20,200 --> 00:16:27,280
normally when it's entirely all code. We can't just name these property names whatever we want.
183

184
00:16:27,280 --> 00:16:34,440
For example, if I call this temperature, then this decoding process is not going to work,
184

185
00:16:34,540 --> 00:16:40,390
so I have to make sure that my property names match the names of the properties that I'm seeing in my
185

186
00:16:40,390 --> 00:16:41,580
JSON data
186

187
00:16:41,770 --> 00:16:43,490
precisely.
187

188
00:16:43,960 --> 00:16:48,790
So this temp that I get back is a number with decimal places.
188

189
00:16:48,850 --> 00:16:57,680
So let's make that a Double data type. And now that we've created this Main struct, we can use it here
189

190
00:16:57,890 --> 00:17:00,890
as the data type of the main property.
190

191
00:17:00,890 --> 00:17:02,810
So let's add that right there.
191

192
00:17:03,410 --> 00:17:11,540
Now, this error goes away, but the error inside the Weather Manager also goes away because our decoded
192

193
00:17:11,540 --> 00:17:19,310
data which is of data type weatherData, now has a property called Main which holds a Main data type,
193

194
00:17:19,820 --> 00:17:21,920
which has a property of temp.
194

195
00:17:22,070 --> 00:17:30,380
So three steps to get to the temperature. But if we go ahead and run our app and I type in, let's see
195

196
00:17:30,380 --> 00:17:37,590
what the weather's like in Paris again, hit Enter. You can see that I'm getting the temperature printed
196

197
00:17:37,590 --> 00:17:42,000
now from our decodedData.main.temp.
197

198
00:17:42,000 --> 00:17:45,300
And in Paris, it's a lot nicer than in London
198

199
00:17:45,300 --> 00:17:50,300
as usual. So now for the final thing that we want,
199

200
00:17:50,320 --> 00:17:54,960
what if we wanted to get a hold of this description right here,
200

201
00:17:55,000 --> 00:18:00,250
how would you go about getting it using our JSON decoder?
201

202
00:18:00,280 --> 00:18:03,760
So this is going to be set as a challenge for you.
202

203
00:18:03,790 --> 00:18:11,410
Take a look at the data in Chrome using the URL and using the JSON Awesome tool to get the path
203

204
00:18:11,830 --> 00:18:14,770
of this particular description.
204

205
00:18:14,770 --> 00:18:25,030
Remember that this weather property holds data inside an array, and that's my hint to you for making
205

206
00:18:25,030 --> 00:18:26,050
this work.
206

207
00:18:26,200 --> 00:18:32,620
Try and get this description printed when we request for the data in our text field for a particular
207

208
00:18:32,620 --> 00:18:35,810
city name, and pause the video and try and give it a go now.
208

209
00:18:35,820 --> 00:18:38,760
All right.
209

210
00:18:38,770 --> 00:18:44,590
So the first thing I'm gonna do is I'm going to copy the path and, again, I'm going to replace
210

211
00:18:44,590 --> 00:18:47,560
my main.temp with whatever I copied over.
211

212
00:18:47,560 --> 00:18:54,580
So in this case, it's going to be from our decoded data going to go straight to the weather property.
212

213
00:18:55,030 --> 00:19:01,490
And then within the weather property where I've got a array with a single item,
213

214
00:19:01,630 --> 00:19:05,540
well, I'm going to get the first item in that array.
214

215
00:19:05,650 --> 00:19:14,410
So, now inside this array's first item, I've got a object that has a property name of description, so then
215

216
00:19:14,440 --> 00:19:16,480
description goes in at the end,
216

217
00:19:16,480 --> 00:19:19,630
and that's how I'm gonna get hold of that description.
217

218
00:19:19,660 --> 00:19:27,620
So, now all we have to do is to map that structure in our WeatherData file.
218

219
00:19:27,730 --> 00:19:32,960
The first thing we have is a property at the top level called weather.
219

220
00:19:33,130 --> 00:19:37,550
So I'm going to create a property called weather that matches that exactly.
220

221
00:19:37,720 --> 00:19:44,710
Next, I'm going to create my weather property which is going to be a WeatherData type. And just like
221

222
00:19:44,710 --> 00:19:49,190
the Main data type, we have to create a new object.
222

223
00:19:49,270 --> 00:19:56,890
But this time, instead of simply just having a weather struct as the value of the weather property,
223

224
00:19:56,950 --> 00:20:00,800
it's actually an array of weather items,
224

225
00:20:00,880 --> 00:20:01,860
right?
225

226
00:20:01,960 --> 00:20:05,920
So the weather property holds an array.
226

227
00:20:06,010 --> 00:20:08,090
How can I represent that?
227

228
00:20:08,110 --> 00:20:13,510
Well, I can go ahead and simply wrap this inside a set of square brackets.
228

229
00:20:13,510 --> 00:20:25,190
Now, I can create my weather structure which has a property called description. And so here let's create
229

230
00:20:25,220 --> 00:20:33,620
our description property which is going to be a string, and make sure that our Weather struct
230

231
00:20:33,710 --> 00:20:37,120
is, again, Decodable for our JSON decoder.
231

232
00:20:38,090 --> 00:20:47,570
Now, if we go ahead and run our code, then the errors go away. And let's check the weather for Beijing.
232

233
00:20:49,180 --> 00:20:57,070
And you can see that in Beijing there is clear skies all around and we're getting that through decoding
233

234
00:20:57,310 --> 00:21:06,220
our JSON data using the JSONDecoder from Swift, and we formatted the data using these Decoable
234

235
00:21:06,220 --> 00:21:07,480
struct,
235

236
00:21:07,480 --> 00:21:12,590
and finally, we're printing it out. If it's still confusing,
236

237
00:21:12,640 --> 00:21:19,840
I recommend just taking a look at your JSON, trying to get hold of different values from this JSON,
237

238
00:21:20,200 --> 00:21:26,840
and having a practice by adding more structs and properties. But in the next lesson, we're going to use
238

239
00:21:26,840 --> 00:21:34,840
our decoded data and format the data so that we can put it into our UI. For all of that and more,
239

240
00:21:34,850 --> 00:21:35,830
I'll see you on the next lesson.
