How to use API in App (Photo Search) - Swift 5, Xcode 12, iOS 2021, APIs

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what is going on guys welcome back to another swift video in today's video we're going to be taking a pretty deep look at how to use an api and this is entirely from a beginner's perspective so here's the app we're gonna make it's a photo search app so in the search bar up here we're gonna start by let's say typing nature maybe and we're gonna try to spell things correctly i'm gonna hit enter and we'll see a bunch of nature related photos load in here we'll talk about you know how to call an api how to change it into things like images here and we can even change it and search for something else let's go ahead and search for uh airplane here and we'll see that a bunch of airplane related photos pop up so that all said let's get started by destroying the like button for the youtube algorithm uh hit subscribe if you're new to the channel get xcode ready get pumped let's talk about some apis in your ios apps quick pause before the video this video is brought to you by ios academy dot io head on over to check out the newly launched tick tock and swift ui courses learn to build world-class professional apps in a fraction of the time quickly and efficiently that said let's get back to the video all right we're gonna go ahead and get started by opening up xcode and creating a brand new project here we're going to stick with the app template under ios and we're going to go ahead and call this project photo search once you do that make sure your language here is swift and your life cycle is in fact ui kit go ahead and continue we'll save this onto our desktop and the first thing we're going to do is expand our xcode window close this right panel and jump into our view controller file here where we're going to write all of our code and i'm also going to hit the play button at the top left to build and load up our app into our simulator here so cool now that we've got that good to go the next thing we want to do is actually find an api to use so i have got the unsplash api opened up here it's a free api or you can search for images i'm going to link it down below but if you head on over to google and just search for unsplash api you can go and create a free account and register an application here we've called it photo search and once you register an application you'll get all this information about it but we're going to want to scroll down to the section that has our key and our secret so let's see i think i passed it somewhere here here it is our access key and our secret key these two pieces of information are going to be used when we make our api calls to identify you know which application is using the api the second tab that i've got opened here is the api documentation and unsplash has some pretty great documentation here but what we're going to go ahead and use on the left hand side if we scroll there's a bunch of different uh api endpoints but we're going to use search photos and if we just go to the literature here we can see that the url takes a bunch of optional parameters but actually they have a nice example right here that i've got highlighted where you would call basically api.onsplash.com slash search photos etc etc and this third tab that i've got here is an example a url which also has our client id inside of it so i'm going to call it rather copy it and i'm going to paste it at the top of our view controller here and we're going to look at it and take a look at you know the various components so i'm going to call this a url string and we'll paste this in here and if we start looking at it the first part of this is basically the api url then we've got a bunch of parameters so we're saying page one we can pass in a query of what photos we'd like to go ahead and search and then here we are passing in the client id which is our access key from this first tab we took a look at here so this is basically the url that we're going to call and we call this url we're going to get a bunch of json data back and what we want to actually do is be able to get this data into our app and we're going to somehow parse these into objects that we could use uh in the app and in this case we want to pull out uh from the urls here we're going to pull out the full image url and that's going to go ahead and you know be a url to the photo we found so cool that all said let's start writing some code it's a lot of theory but let's take a look at how we want to go and do this so the first thing we're going to go ahead and do is we're going to create a function that's going to be called fetch photos and in here we want to go ahead and make a network call to this url so hypothetically we can make the url dynamic right now we're querying for you know office photos and we can let the user type in any search word search term and you know pass that in but let's start off with the bare basics so we're going to come in here and create a url session dot shared and we want to create a data task with a url and a completion handler and we want to stick with this one here and the first thing we want to do is convert our url string from up above into a url object so we're going to say guard let url is a url where we pass in our string and the reason we need to bind it in a guard let statement here is our string might be just completely malformed invalid so that wouldn't be a valid url object so now that we have that url passed in we have a completion handler here and this closure will return to us data from the other side of the network call a url response which we're going to pass in the underscore here because we're going to ignore it our data actually will contain the bytes we get back the response naming is a little misleading and the last thing here we get is an error which will be optional you know if something goes wrong so in our closure we're gonna unwrap the data and make sure we got something and then we're gonna unwrap uh rather we're gonna validate the error is no uh you know implying that something didn't go wrong or we're good to go now that we have a task created to kick it off we're going to say task dot resume and what i'm going to go ahead and do is i'm just going to add a print statement here and we are going to say got data let's go ahead and give this a run but before we do that we want to call this fetch photos right here at the bottom of view did load and let's go ahead and run it in the simulator and let's make sure we're getting our print statement out and once we do that we can focus on the next piece so cool so down here in our console we have got data printing so that means our network call is definitely successful the next thing we want to do is basically convert that data which actually comes back in the form of bytes into you know this json structure that we see here uh you know it's a dictionary key value pairs and the way we can do that is by using this really cool thing built into swift called codable so we're going to create a struct that is called api response and we're going to say it conforms to the codable protocol and in here we basically want to specify the same keys that are in our actual response so total total pages and results now we also want to make sure the types match so swift basically will take you know whatever the names are in here and the types and it's going to try to convert the data into this uh basically one to one so let's make sure we type it all correctly we have total total pages both of those are ins and then we have results which points to an array of these result objects so let's go ahead and create a result which is an array of results i guess we can go ahead and call it and results i believe this one was plural result here is going to be another struct which is codable now it's okay to omit some of the keys you don't need to necessarily add every single one because that would take forever the things that we are going to add i guess we can do the id so let's say let's id which looks like it was a string since it was in quotes for the value here and we care about the photo url so i'm going to create urls and this is going to be another struct and we're just going to care about the full which points to another string so we are going to say let's urls will be urls urls is going to be another struct once again codable and we just care about full we're going to ignore everything else and now that we have these trucks that we want to basically take the data and convert it into once we get it back from our api call what we can do is we can use something called json decoder to do that so instead of printing here what i'm going to go ahead and do is create a do catch statement and we are going to say let results is going to be json decoder json decoder and we're going to basically say try to decode the data into one of our api response models and it's basically just a struct up here and what swift is going to do it's going to try to look at the keys and the types and try to convert everything in the json to and if something goes wrong we're just going to print out an error here but if something doesn't go wrong what i'm going to go ahead and do is we will print out results dot let's see results.results.count and maybe i'll go ahead and say let's go ahead and call this json results so we don't have any confusion in our naming so if we go ahead and hit command r now once again it looks like we have an error here let's take a quick look at what's going on let's see we would need to prefix this json decoder with the word try this call can actually throw an error hence uh we put it in a do catch statement go ahead and hit command r to build and run and our console now we should see something printed out so it looks like we have 10 of these results coming back so we probably want more than that so let's go back to our api documentation here and if memory serves there is a parameter we can add which is per page if we take a look here it's the number of items per page and it defaults to 10. so we want more than that to come back so let's go ahead and add this per page to our url string here it's going to be a get parameter so i'm going to stick it right here in front of uh page equals 1 we're going to say per page is 50. that way we'll get 50 results back let's go ahead and run it and make sure we actually get 50. all right let's say we got 30 which is probably uh the api's limit per call so cool now that we have those let's uh go ahead and let's let's talk about how we would present these on the ui so the first thing i'm going to go ahead and do is we probably want to save this as a global property so we can go ahead and access it in our ui update code so we want to save basically a array of result objects like this so i'm going to take that we're going to stick it right up here it's going to be a var and by default it'll be empty once we get the data back we are going to say self dot results equals jsonresult.res now we don't want to cause a memory leak so we are going to say weak self here at the beginning of the closure if you're not familiar with uh you know weak references take a look at my other videos about it but we'll add a question mark here because it's self optional now and i'm also going to go ahead and wrap this in a dispatch q main async call which is how we want to always update our ui since we'll be on the main thread now we don't really have any ui yet of course if we take a look at our app it's totally empty so we want to basically present all of our images here in some type of ui now what i'm going to go ahead and do is we are going to create a basic collection view here which is kind of out of scope for the networking and api aspect of the video but just bear with us we're going to create a private collection view right here and it's going to be of type ui collection view optional and i'm going to go ahead and set this up directly in our view to load function we're going to create another collection view here instead of using that optional one and i'll show you guys why in just a moment so we're going to create it with a frame of zero and the layout of layout we're going to create the layout right above this it's going to be a ui collection view flow layout just like that and this layout can specify basically how big every cell is and the direction it's going to scroll and all that good stuff so we're going to say scroll direction is vertical we'll say the minimum line spacing is 0 and i'm also going to say the minimum inter item spacing is zero and finally we're going to say the item size here is going to be cg size and let's say 200 let's actually do it dynamically let's go ahead and say this is going to be view.frame.size.width divided by 2 and the height will be the same so it's a nice square image and let's see once we've gone ahead and done that you want to go ahead and add this as a subview we're going to say view add sub view the collection view and then we're going to assign that collection view to our global property of collection view the reason we use another instance here is so we don't have to deal with the fact that this thing is optional so before we go ahead and add this as a sub view i'm also going to assign its data source to self now you'll see an error on this line because we haven't conformed to the data source so let's go ahead and do that we're going to say ui collection view data source just like that and this data source has a number of required functions i believe a two so we're going to say number of items in our collection view we're going to return the number of results that we have and keep in mind this results thing that we're referencing here is our array of results and by default it will be zero the next thing we want is cell for item at index path and in here we need to dequeue a cell and return it so we're going to say cell is a collection view dq reusable cell with an identifier and index path so we are going to use let's see this one right here we haven't uh registered anything to our collection view yet so we'll say cell index path and we are going to return and just for the sake of you know just starting off we're going to set a background color to this cell i'm going to say it is blue and let's see we also want to register that cell we used a string here for the identifier we also want to return the cell to the function so we get rid of that error now to register a cell we are going to come up here and say collection view and we are going to register a ui collection view cell dot self for the identifier of cell and once our api call comes back which is all of this stuff after we have updated our results since we're reassigning it here we're going to say self that collection view we're going to go ahead and say reload data the reason we're saying reload data now is because we have updated our results which we have you know as a global property up here when we reload our data our number of cells should now reflect a new number of things and results and our number of actual blue squares that we see should also reflect it so i'm going to hit command r to build and run and we're going to take a look at these blue hopefully squares showing up and the reason they're actually not showing up is because i forgot to do something super important and that is give a frame to our collection view here so we have not implemented uh you know a frame for it and all of this stuff is in muted load so we want to go ahead and override view did layout sub views and i'm going to say super if you did layout subviews and i'm going to assign our global collection views frame size to be the entirety of the controller's view frame and we should end up seeing some blue squares all right looking pretty good so we see a bunch of these blue squares it's kind of hard to see where one starts and the other you know begins uh because we don't have any spacing between them but we didn't come here to see blue squares we want to see our actual images so what we need to now do is we need to basically have a custom cell here to which we can pass our result url and where we can actually you know download that image and show it in the cell so that actually brings us to the second part of you know api calling which is how do you download an image from a url so when we say cell for row rather cell for item at index path here we can actually get the relevant result out of the results collection so we're going to say from results give me index path dot rows element from that we want to get urls and then from that we're going to get the full url so we can actually call this url string we can call this image url but now we want to create a custom collection view cell that actually has an image view in it where we can show that particular image so we're going to come up here and create a brand new file and it's going to be a coco touch class and we want to sub class a ui collection view cell and i'm going to go ahead and call it image collection view cell make sure your language is swift and go ahead and create it the first thing that we want to actually do in here is create a static let's property called identifier and similar to how we used the string for cell in our view controller here not only to dequeue it right on this line as well as you know registering it up here what i think is really good practice is just create that as a string in here i like to use the same name as the class and that way you can ensure you don't have any typos in the string the next thing you want to do is override the initializer which has a frame and call super in it with the frame just like that you'll also need to bring in the required initializer for this class not really relevant why you need this kind of out of scope but go ahead and add those we'll also need layout sub views call super layout sub views you're gonna need to override prepare for reuse say super prepare for reuse and the final function we'll need to create on here is configure with url which will be a string so let's talk about each of these components so we have initializers here but we don't have any image view in the cell yet so we're going to declare an image view here we're going to say private let's image view is a ui image view and we're gonna create it with this anonymous closure pattern uh which allows us to configure all of our uh you know properties stuff directly in this curly brace block so we're gonna say it's a ui image view we'll return it here and we're also going to say that it clips to bounds so nothing overflows and i'm also going to say its content mode is going to be scale aspect fill now once we've gone ahead and created an image view here we want to definitely add it as a sub view but we're going to add it to the content view uh that's kind of a relevant detail of any type of cell so let's uh continue along instead of focusing on that for a moment we want the image views frame to be the entirety of this cell's content view so we're going to say it's frame equals content view dot balance now in prepare for reuse this is the function that gets called every time you know the cell prepares to be reused hence the name and finally this is the most important function this is the function we're going to call from our view controller where we pass in the url for the image so the first thing we want to do is create our image url from the string we can actually even call this url string we can say guard let url is a url object with a string of url string and if we're not able to create it we're going to go ahead and return and now we want to use a network task to actually download the byte for this image we're going to say a task is a url session shared and we're going to say data task that's going to have a url and completion url completion takes data we're going to ignore the second http response and then optionally it also has an error in case something goes wrong we are going to want to unwrap the data since it might be nil we're going to validate that the error is in fact nil and once we have this we can actually create an image with this data but we want to do that on the main thread because the uh image is actually part of a ui you know a ui object so we want to say an image is a ui image or we're going to create it uh with some data and we can pass in data just like that and finally we're going to assign this to our image view so we'll say the imageviews image is our image and because once again we're in a closure we want to go ahead and say weak self here and make this self dot self optional and don't forget to say task dot resume to actually begin this url session task one other thing you could do is just get rid of this task assignments and you can just say dot resume at the end of this block both are totally acceptable so cool now what we need to do is actually call this configure function and register the cell back in our controller so we're going to come back to our view controller and at the top here where we registered this vanilla collection view cell we're going to register our custom cell dot self with our class name dot identifier which if you recall was that static property we added if we click jump to definition we'll see it right back here and now that we registered it we also want to use this so in the cell for item at index path we want to use our new identifier we want to try to cast this cell as our custom cell and we are going to say guard let in case we are unable to cast it we are going to fall back to a normal ui collection view cell you should not have any problems casting it but let's see if we're not able to do that we'll fall back there otherwise what we're going to say is we can now say here cell dot configure because we have casted our cell to our image collection view cell we now have access to that custom configure function we wrote and we can pass in our image url string just like that and if you recall back in our configure function we take that url we try to convert it to a url object and then we pass it into another networking call here to download the image data for the url and then we stick it into the image views image so let's go ahead and hit command r we wrote a ton of code let's make sure that works all right bear with it we should see our images load up here in a moment there's one two now you can see they're asynchronous so it's a little slow as they do in fact load in some of them are faster than others some are significantly slower we are actually getting the full image here so if we look at the json it probably has lower images too here we have small and thumbnail let's we can also do regular if we wanted but we have this working now and as we scroll you can see here actually that it's loading in the other images too one thing you'll notice is if you actually try scrolling back up what's going to happen is it's going to try to load those images in again and the reason for that is we're not caching the images as we have downloaded them scroll the cell off screen and scroll them back caching is a whole other video and i want to keep this focus to the api call but the takeaway here is we're going to the network we're fetching this json from this api and then we have a way now to convert it into these images and then download that image as well from the url so let me go ahead and let's add one more thing to our app here before we wrap up and that is a way to search for different images because these office photos are nice but we can probably do a little better than this now before we do that i'm going to actually instead of using the full image here i'm going to change this to use the regular image so they load in a little faster so we're going to come into this and instead of full here we're going to do regular and we also need to remember in our cell for row or rather cell for item we want to change this to be regular as well go ahead and give it a command r to build and run and your photos should hopefully load in a little faster now that they're you know not as large you can also go with the thumbnail image here or small in our json we're just sticking with regular so cool how do we actually allow the user to search uh it's pretty simple what we want to go ahead and do is we want to add a search bar at the top of our app here so um what we're going to do is we are going to declare a search bar which is a ui search bar just like that we're going to add it as a sub view at the top of view did load like so and we also want to go ahead and assign these search bars delegate to self and we want to conform to that protocol and the reason we need the delegates is because there's a function on there that we can uh you know call when that gets called rather when the search button gets clicked and let's see search clicked if we take a look at this there's a function in here called search bar search button clicked when we actually go ahead and uh you know get the click event here we want to actually fetch photos so right now we're fetching photos you know as soon as the app launches and view to load i'm going to delete that and what i want to say here is we're going to say fetch photos and it's going to have a parameter of query and we're going to take this query parameter and what i'm going to go ahead and do is instead of using this url string global thing here i'm going to grab this whole url and do a command x to cut it and we're going to come down to that function and instead of using the word office in the string here for the query we're actually going to stick in the parameter that comes into the function thus making it dynamic so once we have uh done this what we want to do is we're going to say if let's text is the search bar dot text uh just like so what we can go ahead and do is we can say fetch data rather fetch photos for this text and before we do that we are going to make sure we empty out our results we are also going to reload data on our collection view so we can go in you know remove the photos from the prior one from the prior search term and this should go and kick off another api call finally we want to give our search bar a frame so right here in muted layout sub views we're going to want to tweak this a little bit so i'm going to say search bar and we want to give it a frame just like the collection view so we're going to say cgrect and here we're going to say this is 10 from the left and from the top here we want to use the safe areas i'm going to say this is safe area insets dot top this will be the width of the entire view so we'll say view dot frame dot size let's try that one more time frame size dot width subtracting 20 because we said 10 from the x side which is the left and the height is going to be 50. and our collection view now is going to be cgrect and this is going to be zero from the left we're going to say view dot safe area insets dot top plus 55 so it's not overlapping our search bar the width will be view.frame.size.width so it's the entirety of the width of the screen and finally our height is going to be view.view.frame.size.height subtracting 55. all right once we have done that there's one thing i forgot to do and that's when this search button is clicked we want to get rid of the keyboard on the search bar so we're going to say search bar resign first responder so we've written a ton of code here let's go ahead and run it and let's see what we've got going on and if everything is functional we'll do a quick recap so right now we have this black empty screen here and a search bar up here you might be wondering why do we have a black screen because we had a white background in the beginning and the reason is we can actually fix it is the default background color of our collection view is black so i'm going to say our collection view's background color is going to be system background which for those of you who don't know will be white in light mode and black in dark mode and we have our search bar up here that we can tap in now if you see the cursor but not your keyboard you need to come up here to your toolbar and hit i o keyboard and you want to toggle the software keyboard and you'll see the keyboard pop up like that and let's say we want to search for images of ocean type in the ocean go ahead and hit enter and it should kick off a api call and what you'll notice here is we get a bunch of pictures of the ocean and we can scroll down and load in the other pictures it's a scroll back up here let's search for something else so i'm going to delete all of this and we're going to search for mountains and hit enter and boom we have a bunch of mountains so let's uh do a quick recap here of the search behavior and then the whole thing because we did write quite a bit of code so to get the search functionality working we basically added the search bar here at the top of view to load we set its delegate so we can get the event when the user hits the enter key we add it as a sub view now in view to layout subviews we adjusted the framing for the search bar and the collection view so we can fit both of them on the screen when the search button is clicked we call this function we get rid of the keyboard by telling the search bar to resign as the first responder we unwrap the text from the search bar in case the user you know just entered a bunch of spaces and if we have text we reset the result in collection view and call this fetch photos and pass in the query text now we also move the url string locally into this function so we can dynamically stick in the query term into the string now we also then go ahead and make an api call via url session with a url and a completion enclosure we learned about codeable and creating uh you know those struct models from the data we get back with this do catch and our json decoder and then down here we have a bunch of collection view stuff which is you know pretty unrelated to the api business but that's how we actually render out you know this nice grid of photos for the images in each cell we did need to create a custom collection view cell here which is a sub class of a collection view cell we have a cell id we have an image view in here we are laying everything out and then the important thing is we add this configure function that can take in a url string for an image it converts it to a url object and it can go ahead and create a session task to convert that url uh get the data from it and convert it into an image so that is an api in a nutshell and what's really important once again takeaways from our browser over here is your codeable models need to match basically the keys which is the keys over here on the left hand side of all the colons and the types need to match two so total would be the key the type would be an integer most apis have pretty good documentation unsplash is a really good one to get started because it's a fully free b they have a pretty extensive api with a bunch of different things you can do here and see it's very well documented and of course all apis you'll have some sort of you know authorization some type of key here's an access key or a secret key you know you definitely don't want to be sharing these with anybody of course i'm sharing it for the purpose of this video i'll probably deactivate these keys after the video goes up so definitely head on over to unsplash.com and create your own uh application keys and account so that's basically all i've got for you guys fully functional api driven photo search app here let's search for one more thing let's search for youtube let's see what we get uh searching for youtube and boom we have a bunch of youtube related images so once again i hope you guys found this video helpful it definitely covered a lot leave a comment down below if you're confused on anything if you have questions i love helping you guys out as much as i can if you haven't liked the video yet make sure you destroy that like button for the youtube algorithm and most importantly hit subscribe for daily swift uploads and to join the ios academy community thanks for watching i'll see you on the next one
Info
Channel: iOS Academy
Views: 7,461
Rating: undefined out of 5
Keywords: swift 5 tutorial, swift 2020, swift, swift 5, swift tutorial, swift for beginners, swiftUI 2020, swift programming, swift basics, swift apps, make iPhone app, swift make first app, swift api, swift url session, swift download image, codable, URLSession, swift use api, swift get JSON, swift app json, app, ios, swift api 2021, swift app example, swift photos, swift download photo, swift download, swift api call, swift network call, swift GET call, swift api url, swift search
Id: IQ4jh4EfVOM
Channel Id: undefined
Length: 35min 59sec (2159 seconds)
Published: Sun Jan 24 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.