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.