Build Weather App in Swift and Xcode 12 (Tutorial) - iOS 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] everyone welcome back to another Swift tutorial in today's video we're gonna be learning how to build a full-fledged weather app so the app we're gonna be building is this right here and this is actually using your current location to fetch weather data and we show the daily forecasts including the day and icon low and high temperature as well as the current temperature and an hourly forecast and as you can tell this app is very similar to the native weather app that Apple has built and that this ship as a part of iOS so with that being said this is gonna be a bit of a longer video I might break it up into two videos if it gets a little dragged on please hit that like button down below if you're excited get your Xcode booted up and let's get into it as per usual let's start with a new Xcode project we're gonna stick with a single view app and we're gonna call this my weather we're gonna save it on our desktop give ourselves a little more room to work by expanding Xcode and let's start talking about the pieces we need to get this weather app working so first and foremost we're gonna need the users location and the location is to allow us to get weather for the current area we're gonna use core location to accomplish this the next thing we're going to need is a way to show a list of weather for the upcoming days and we're gonna use a table view to do that we're also gonna need a custom way to show that horizontal aspect of the table which shows you the hourly forecast for the current day and we're gonna use a custom cell with a collection view to do that and let's see we're also gonna need an API slash request to the data so we're gonna need that and essentially these are the four large components that we need to knock out to get this app up and running in addition to this we need to do some other little setup that we'll do together and the first little thing we need to do is drag in some icons for different weather types and I've actually gone ahead and created a couple for rain cloudiness and as well as sunny weather and we're gonna start by going to our assets and we're gonna create a asset called clear rain and cloud so let's select clear and bring in this icon whoops let's not bring them all in let's get rid of that put the Sun there for cloud let's bring in the cloud whoops not that one let's get rid of that bring in the cloud and for rain let's bring in the rain icon now let's go back to that view controller and let's start tackling these with easiest to most complex so the table view is pretty easy to set up so let's sit at the table view first and foremost so we're gonna add a outlet for a table and we're gonna create a array for models and this is gonna be an array of let's just call it weather objects that we're gonna be creating later on let's just mock it down here as a struct so we don't get an error we also want to set the tables delegates and it's a datasource let's add them up here so UI tableview delegate as the tableview datasource we also want to register to custom cells one cell is gonna handle that collection view custom cell for the horizontal scrolling for hourly forecast and one of the custom cells is gonna just handle the normal vertical cell that shows the current day of the week the weather icon as well as the lower and upper temperature for the day so let's just comment out register two cells we also need to implement the basic table functionality and that is a number of rows we're gonna return a number of models dot count and we want a cell for row and for now we're just gonna return a UI tableview cell make sure you have a simulator selected up here and hit command B and your app should still be building without any errors let's come up here and create a folder for our cells so the first one is going to be let's see whether cell the next one will be our Lee collection so let's right click on each of these and create the respective cells which is a new cocoa touch class we want a UI tableview cell and this one is a weather table view cell let's create a nib also by checking that box and let's create one more this one is going to be the hourly table view cell like so and let's just quickly add the identifier and neighbor functions in here to register the cells so we don't forget later so static let identifiers and static func mid it's gonna return a UI nib and let's spell static correctly and it's gonna be a name with a name and a bundle the name is gonna read the same name of this class here and here and let's copy this and also drop it on in to our other cell and don't forget to update the identifier for both the nib and the property and let's go back to our view controller and in here let's a register those cells real fast so let's say the table register a nib and the first one we want to register will do hourly dot nib for the hourly dot identifier and the next one we want is the weather table view cell so let's just change this to weather and let's also change it over here hit command B your projects would still be building something important to call out here the order that you register cells is irrelevant as long as the cell is registered before it is used that's the important thing so a common question that I've gotten in the past if the order matters it does not so this is basically a very simple version of the table let's focus on well actually before we move to the location let's go to the main storyboard and let's bring a table in and connect it and run the app and make sure it's not crashing so let's grab a table view drop it in connect our table outlet and let's add some constraints which will pin the table to all four sides of the screen hit command R and let's see if this app crashes hopefully not so app is not crashing awesome so what do we need to do now let's move on to getting the users location which personally I think is kind of cool so let's get rid of this we want to import core location which is the framework Apple provides to be able to do this and let's see let's put the location stuff in between the table in this comment we're going to need a property which is going to be the location manager which is a CL location manager and we're gonna create a function which is gonna be let's see we'll call a setup location and we're gonna say location manager first and foremost the delegate is self location manager request authorization for when in use so the user is gonna get a permission prompt to allow location access when the app is in use and after that we're gonna say location manager dot start updating location we also need to come up here and add the location manager delegate the CEO location manager delegate we're also gonna have another property where we're gonna capture the current coordinates of the user and when testing this in the simulator you can actually provide like a mock location so we're gonna pick something random I think New York is one of the ones in the list so I'll see if that's there we'll use that so we're gonna say coordinates is a CL location [Music] see a location it'll be optional to begin with and the delegate function that we want is location manager did update locations I believe it's called let's see did update locations and this has a parameter which is an array of CL location so we're gonna say if locations isn't empty and we're gonna say we're gonna make sure that this let's call this current location but we're gonna make sure this current location is still a nil in other words we haven't set a location yet so current location is nil then we can say the current location is location locations dot first and once we have a location in here let's actually stop updating the location save on battery life and after we have a coordinate there's no need to continuously monitor the location and we're gonna call another function which is gonna be request weather for location and we're gonna implement that and just a sec before we do that in here let's just print out the longitude and latitude for this location so longitude is going to be current location dot bleep coordinates yep dot coordinate da longitude and let's do that for latitude as well and let's actually do this as a guard let's actually guard this current location just to make sure that it's not nil before we use it and we can get rid of this question mark for both of these and let's print out both the launch and the lat so hit command B you should still be building before we run the app something super important that we need to do is go to the info.plist and add a string in here which is required by Apple when requesting any kind of permission so we're gonna add privacy location when in use and you can a tab it will autocomplete it for you and we're gonna provide a string along the lines of please allow location to see local weather so let's hit command R to run this in our simulator and looks like we don't get a prompt for location so let's come up here and go to debug and there's location in here and you can see it's up to none let's set this to be Apple and let's rerun the app my head and command R and let's see it looks like we still are not getting the location pop-up so let's go back to the view controller and see what we missed let's see so location setup is done in here and looks like we're not calling this function so obviously we're gonna call this function for anything to happen so let's call this function in instead of viewdidload let's call this function and if you did up here we're gonna do a super view to tap here and we're gonna call this function so hit command R one more time and there's our awesome location prompt let's do allow when using app and we should get our longitude and latitude printed out here which we do so this is a longitudinal latitude I believe for Apple which is the location that we just selected so that would be Cupertino California so cool so now we have the location and the next thing we want to do as I mentioned is implement the function to actually go and fetch weather so to do that we need to request the data from an API so I'm gonna head to my browser and talk about this API that we're gonna use so if you're not familiar dark sky is a really awesome a weather app available on iOS Android and I think other platforms too and they actually offer their API services to get weather data for free to test and develop stuff if you want to actually use it in your app you do have to pay them however there are several other options out there for free weather services but we're going to use this as an example you can go here and get a free API key to test and play yourself but basically I already took the liberty of reading through there pretty well-defined documentation and finding out that this URL here basically returns a bunch of weather data for the supplied longitude and latitude so if you look at this we get a bunch of things like the hourly forecast the daily forecast current forecast we've got temperature time weather like description we got a bunch of data in here so what we need to do is take this URL and request from it the weather based on the location coordinates that we have so let's come into our code and instead of printing out a longitude and latitude let's create our URL which is API dark sky net forecasts my API key which after this video I'll probably be deleting so please create your own like I mentioned it's free slash the longitude and latitude and we want to exclude some fields because they also return minute Lea forecast which is pretty crazy so if we come back here we can see the longitude is this negative number and the latitude is this positive one so let's come back here and replace the longitude which is this one with longitude and this one with latitude next what we need to do is use this URL to actually make the request let's get rid of my antivirus pop-up and to make a request we aren't going to use the URL session data task so we're gonna use a URL session dot shared data task with URL with the completion let's create a URL with a string and we're gonna pass the completion block data a response and error so data the response error in and in here we're gonna do a couple things so first we need to do some validation and that validation is let's make sure we got data back and that there is no error then we need to convert data to models slash some object that we can use in our code thirdly we need to update user interface so the first part is easy we can say guard let data equals data and error is new otherwise let's return and we can print out something along the lines of something went wrong next we need to convert the data to a model or some object so swift has this really nifty thing called JSON decoder and what it allows you to do is basically create a struct object that conforms to the codable protocol and as long as the properties that you put in here match the properties that the data returns particularly in this JSON format so for example this latitude is a floating-point time zone is a string if all of these match you can use Swift Swift's JSON decoder to convert the data to this object the important thing is you need to make sure that you have accounted for all of the keys in the response and as you can see there's quite a few of them as well as the nested ones in this hourly and daily array so I'm gonna pause the video here and type all this out and come back in just a couple minutes that way you guys don't want to say I want to type all this out now we've gone ahead and basically created struct objects here based on the keys in this JSON response so we're gonna get so the top-level response is this thing which we've called weather response and the three things of note in here are currently hourly and daily each of those have a couple things well a lot of things currently has all of this stuff daily has an array of data of these daily weather entry objects same thing for currently I'm sorry hourly we've got we've got these hourly objects and each of these objects as you can imagine for hourly is information about weather on the hour and for daily it's about weather every day so we're gonna actually delete this weather struct that we initially created which is what we're using in the models array and we're gonna use one of these our table view is gonna show a list of the daily weather items so we're gonna actually put this daily weather entry into our models array so let's come up here before we continue on our request of getting the data so now that we updated that up here we should hit command B and still be able to come the app let's come down here and continue with this now that we've defined those models we're gonna decode this response data to that model and the way we do that is we're gonna say this is whether results and we're gonna do a do catch statement which basically tries to use JSON decoder to decode whether response from the data if an error occurs we're gonna print out error and pass in the error property and let's see let's get rid of this print for the URL to actually get this request to fire off we need to add a dot resume at the end of it slightly misleading terminology from Apple cuz this resume actually kicks off the initial requests which I guess they've called resume for whatever reason but basically once we've done this do catch if we're successful we're gonna say guard let results equals JSON to unwrap the optional and let's just print out something on results so let's do result dot currently and I think there's a summary on here and if you're curious where these properties are coming from these properties are in this all the all of these like JSON struct codable struct things that we created so the reason we create them is so that this JSON decoder can map the data for us pretty conveniently so let's hit command R and we should get some something printed down here so we get printed down here partly cloudy so awesome so if we actually look at the data I actually paste it in the URL for this request that we're sending for Cupertino it's partly cloudy somewhere in here and I'm actually not gonna waste I'm trying to find it because there's tons of data so that said what we need to do now is we need to update our models array and reload the table view so the way we do that is pretty simple let's get the list of daily weather entries and that will be results dot daily dot data and we're gonna say self models append contents of entries and then we just want to reload the table view so let's do a dispatch Q dot main dot async self dot table reload data don't worry about this dispatch Q main async at a high level it just tells the program to make sure the stuff that's going on in here is done on the main thread so it gets updated on the on the user interface quickly I'm not gonna get to the weeds of this but just make sure you wrap your table if you reload in it so let's go implement our cell now for the table view if you recall we have two cells one is the weather cell and the other is the hourly table view so let's just do the weather one right now because that's what we're gonna show first so let's DQ a cell so let's cell equals table view DQ reusable cell with an identifier and it's gonna be weather table view so identifier index path as a weather table view cell and let's click into the table view cell and we're gonna add a function in here to configure the cell and it's gonna be a configure with model and it's gonna be deal their entry let's go back to our viewcontroller and call that configure function configure with models which is our array of those weather entry objects and let's see what else do we need to do so why is this complaining this is saying can I convert value of daily weather entry to expected argument type of protocol so that doesn't seem right let's say command B and C what we messed up so if we go back to this configure let's see configure with model daily weather entry let's click into this this is a struct that is codable so this doesn't seem right let's see what we messed up because we need to use the correct function name I've actually done this before so let's not use conform let's use configure and hit command to be and everything compiles let's go implement that table view cell so each table view cell in our list is going to show the day that we're showing the weather for an icon the low temperature and the high temperature so let's do a couple things let's get rid of this commented code firstly let's set a background color just so we can like distinguish the cell a little more easily let's do gray actually let's add a outlet for day label and we need two more labels for high temp label low temp label and we want a UI image view for icon image view and when we configure the cell with a model we want to assign all all the stuff so firstly the temperatures are pretty easy to do we can say low temp label that text equals model dot temperature low which is a double so let's convert this to an integer and let's put it in a string and we also want to show the little circle to note eight degrees so I've actually opened that up in Google but I forget what the keyboard shortcut for this is but you can just Google degree symbol and you'll find it so this little symbol let's do the same thing for the high temperature label so again this is gonna be modeled temperature high now what we want to do is configure the day that we're showing and the way that we can do that is basically use another function we're gonna called a label equals let's see get de for dates and I'm gonna pass in a date and it's gonna be model let's say time interval since 1970 and we're gonna pass in model dot time and we need this to be I believe a double if I'm not mistaken we need to create this function which is going to return a string and it takes in a date so let's see what do we have going on over here so we're saying get de for dates and we're passing in a date object let's create this let's rather make this to be optional because we're gonna try to initialize the date from this timestamp in the model and it might fail let's see we still have an error here if we look at the error we say cannot assign a value of type string because we want to actually be assigning the day labels text and here we need to return a string so we're gonna say guard let input date equals day otherwise let's return empty and to get the day for the date we're gonna use a date formatter and it's gonna be date formatter formatter died date style I believed it does when we want which should be a we could use that's see medium for this but actually let's do date format gives us a little more control and we want the day and I believe the day is notated with three capital M s if this isn't for the day of the week like Monday we can always look it up and last we want to return formatter string from input date so hit command B and we should be good to go for the icon let's just default the icon to the Sun icon that we brought in earlier and we're gonna compute the icon in just a moment I think we called it clear let's head back to our assets file and we have clear cloud and rain and looks like that aligns with what we've got in here hit command B and let's create these outlets on our table views nib for we actually run the app and see the weather so let's go to the weather cells nib and let this load and we got a drag in a bunch of outlets are there a bunch of elements and connect their outlets so the first thing we want to drag in is a label and let's put it in here like so let's set some constraints so zero zero zero and let's make the width of this 66 SKU that's easy and this is gonna be the high temperature let's grab one more label and drop it in and this is also gonna be 66 and width so 0 0 this one we don't want this one's 10 actually from the label on its right zero and the width again is 66 like so let's also bring in an image view for our icon and this one is actually going to be centered in the cell both horizontally and vertically and the height and width are gonna be fixed and we're gonna fix them to be 60 by 60 like so and there might be a little small so let's actually bump up the width and height of this by going to the ruler and changing this value to be able to say 80 and this one as well as 80 lastly let's add one label that's gonna show the current day of the week that we're showing the weather for so we're gonna do zero zero zero and zero hit enter and let's connect our outlets and give suspend so let's right-click this grab our day label firstly connect it next let's grab our high temperature label and bring that all the way over here then we want our low temperature label and let's connect that here whoops I think we missed that let's try that one more time low temperature label and lastly we want the imageview like so and let's not forget to set the identifier in the nib so copy that come back to the nib and paste it in here so hit command R and if I'm not mistaken we should start seeing weather for the Mach location so look at that we get weather we get the Sun showing up in here granted it's not formatted that well we get the low temperature and the high temperature so pretty awesome progress if you ask me now let's get this looking a little nicer let's get the current temperature showing up here like the main weather app and let's also work on the hourly stuff so let's do some cleanup of this user interface and actually we're seeing March here for this day label which is not correct so let's actually fixed that first so I believe let's try for the date format to capital D's that might be the day looks like that's the day of the year let's try three capital D's and that's not accurate either so let's actually search for NS date formatter [Music] and there should be a reference that people oftentimes use from ns hipster I'll just delete this window for my antivirus and let's see this is what we want so we want let's see number formatter so let's see ah so what we want is instead of M or D here we want for ease and if we build and run that you should see the day of the week and hopefully they're in order so today's actually Wednesday so we got Thursday Friday Saturday Sunday so on and so forth so let's decrease the size of this the icon for the weather and instead of actually decreasing the size what we're gonna do is increase the size of the cell height and on the image view itself we are going to set a property which is gonna be a Content mode scale aspect fit let's go to the view controller and in here we're gonna say height for row at index path and we're gonna return a hundred so let's build and run that and looking a lot better let's increase the size of the temperatures over here and let's think both of them centered that way they won't be kind of smushed to the icon so again let's go back to our cell and in here we're gonna say for the high label and low label the text alignment is centered and let's see that for low temp label as well let's get rid of the background color that we added in here and let's see we also want to compute the icon so right now we're just using clear the way we're gonna do this is by using the summary of that date so there's a summary property on the model that we're passing in so we could actually use this but actual let's use the icon so there's an icon property on here and what we're gonna say is if icon contains clear we're gonna use a clear icon else if icon contains rain we're gonna use the rain icon otherwise we'll use the cloud icon so this one's clear rain and lastly cloud so let's update these and hit run and let's see what we get so we can see here we are showing rain for today sunny sunny rain rain sunny and looks like no cloudy which is cool so that takes care of this let's move on to showing the current temperature at the top of this table and to do that we are going to utilize the tables header so let's go back to the view controller and in the function where we reload the tables views data which is our fetch function we're also gonna say self dot table dot table header view equals create table header and put a self dot before there this function we have not created yet so let's create it it returns a UI view and we're gonna say let header view is a UI view with a frame 0 0 dude framed size dot with same for the height and let's return this header view let's set a background color to this red just so you guys can see where this header review is gonna go and what we're gonna do with it this space up here and we want to show a label with the text current location the summary for this location as well as the current temperature nice and large in the middle of this red header view so let's create our three labels are three labels will be summary label which is a UI label and we want a location label and a temp label so let's just assign some dummy text to this for the sake of just quickly positioning everything on the screen and let's see summary let's assign frames to all of this so we want the top label to be location so we want the frame to be a cg rekt within X of 10 y 10 nude frames sighs now with minus 20 and a height of let's say the header views height divided by 5 so 1/5 of the header views height for the summary label we're gonna do the same thing so let's copy and paste this CG wrecked the only difference in here is going to be this is going to be 20 and we are going to add the height of the location label so let's say Plus frame size height and lastly we have the temperature label so let's also go and paste in this business and this is going to be instead of the hot location we're gonna add the height of the summary label as well so Plus this da frame size dot height and the wish we gonna keep the same as well the height for this is gonna be this divided by I believe three let's try two and see if that overflows the header view let's not forget to added these as sub views to the header view so we have a temp label a location label and a summary label and we want all this to be centered also so let's set all of the text alignment to be centered location in summary and temp and we're gonna bump the size up for the temperature in just a second so looks like we need to set this to be the text analytic command R and we should be able to build and run and okay cool so we've got some stuff going on here sizing isn't completely the way we would want it but I think this is sufficient for the sake of this demo so let's increase the size of the temperature and actually assign the proper text strings so location will stay the same let's increase the size of this temperature level and we're gonna assign a font with named Helvetica bold let's try 32 and what we're gonna do in the function where we get the data we're gonna assign the current weather data to a property so we can access it and we're gonna get that current via the results dot currently and it's a current weather and we're gonna say self dot current weather equals current so we're gonna come up here and create a variable called current which is current weather let's go back to this header view function and what we can say in here now is the text for the temperature is self dot current dot temperature and for the summary label we can say this is self dot current dot summary and let's actually wrap this inside of a text block like so and the reason we're gonna do that is because we're gonna add on the degrees notation so if you recall in the cell we added this little circle degree thing in the cell so let's go back to the view controller and add in this and let's hit command R before rather let's check this error first string interpolation produces a debug warning the reason for that is because this is optional so let's actually unwrap it so we're gonna say current weather and we can say current weather so let's it command R we need to return a uiview in here and let's see that I spell it wrong it's like it's spelled correctly looks like we've have an error over here self that current weather equals current then we call the current instead of current weather let's let this run and we get the current temperature with a decimal actually we can probably pop this off we get the summary and we get current location so looking pretty good in my opinion let's get rid of this red color because it's slightly obnoxious and let's set a nice background color to this and we can do that by searching for [Music] some hex in Google and let's pick a nice blue shade for the background let's pick something a little darker so this works and what you can do is you can copy the RGB values in here and let's set the header view dot background color equals a UI color with red green and blue so let's paste in those values and lastly blue alpha is 1.0 let's run this app and we should get a nice blue in the background of this let's also set this at the background of the cell so cell background color is this UI color let's get rid of all this and let's see cell top background color equals a UI color this looks correct let's run it hopefully it's all blue now beautiful so we can see that a factual view is also white still because the tables cells are blue but the background is white so let's actually take this color assignment and also assign the background color of the table and the view but let's spell view correctly because that's important run it one more time and we've got a weather app so the next piece to do which I'll probably do in a follow-up video because his videos gone very long already is add another cell for the hourly forecast here that the user can scroll horizontally so thank you so much for watching if you enjoyed this video drop a like below helps out the channel and the video quite a bit leave a comment if I skipped anything that you're confused about subscribe if you're new for daily videos and I'll catch you in part two so we can add the hourly and finish up this
Info
Channel: iOS Academy
Views: 29,414
Rating: undefined out of 5
Keywords: swift, ios, app development, xcode, learn, tutorial, iPhone, iPad, tableview, getting started, beginners, Apple Developer Program, make app, apps, bootcamp, app millionaire, weather app, swift tutorial, walkthrough, swift app, swift for beginners, full weather app, weather app tutorial, swift get current location, swift for beginners course, swift 5 tutorial, swift 2020, swift build first app, objective-c, use api in swift app, custom tableview cells
Id: Xc6q_JltHSI
Channel Id: undefined
Length: 53min 4sec (3184 seconds)
Published: Thu Mar 26 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.