Hey everybody what's going on this is Caleb with slopes dot com.
And in this video we're going to set up our download service singleton which is going to help us download
data from the get her API.
So go ahead pull open your project and we're going to create a new folder actually we're going to go
ahead and write click on versey app select new group and we're going to call this services because we're
going to put our download service in the services folder it only makes sense.
Also we should create a second folder called utilities and inside utilities is where we're going to
put our constants folder and this Constans folder is going to be used to basically hold variables that
hold reference to certain things that are still very string based like for instance our YOU ARE L's
for our search queries.
K so what we're going to do is we're going to go ahead and actually create that first because we'll
need it when creating our functions.
So go ahead and right click on the utilities group click new file and click swift file.
They call this Constance and press create.
OK so we don't need to create a class or anything but I am going to go ahead and separate these with
a comment and just type Mark dash.
And this is going to be for you or else.
OK.
Now I'm going to create one for the you l needed to search for Trending repositories.
OK.
So go ahead and type Let us trending repo.
You r l and that's going to be a string of course.
And if you remember when we looked at the get hub API it went like this DTP.
Oh my goodness.
H t t p s colon backslash backslash API.
Get hub dot com slash search.
And really I should be copying this from get her.
But anyway repository Torrey's.
OK.
And then we have a question mark.
Q equals and you know what.
Right here this is where your query is going to go so I'm going to say that for now.
And we're going to go ahead and do and sort.
OK.
Remember it allows us to sort it by stars meaning we're going to get the most popular results first
then we can do and well and order equals descending.
That's going to return us the most popular ones first just like that.
Now I chose to go with swift repositories that were popular.
K but you don't have to write you can still you can choose whatever you want.
So I'm just going to go ahead and type Swift because those are the repositories that I was interested
in.
If you're interested in repositories that are written in go you can search for go.
You can search for repositories written in assembly just like the Tetris example from a few videos back.
So this is the you are all we're going to use to download that Jaison data for swift repositories that
are sorted by Sarr stars descending.
I don't know if that's a real word but it is now.
So while we're here we may as well also include a search you are ill.
So go ahead and type let search you are l and this is going to be the U R L we will use when we are
building out our search Visi and it's basically going to be this same exact u r l except we're going
to stop right after the Q and then write a function later that's going to allow people to pass in their
query and will append it to the end.
Pretty cool.
Let's go ahead and let's do that.
So go ahead and just.
Actually we can copy and paste from here like so.
There we go.
And you know what.
Let's actually save this here.
At the end let's just say that is the chunk that we could add in as its own little segment.
So let's just say let stars descending segment
equals and there we go.
Boom.
So this needs to be a string because we want to be able to just tack that on right at the end and that
will allow us to sort it by stars descending Lee and then of course as you remembered in the simulator
when we open our app and we click on the View read me button.
It's supposed to open a Safari Web controller but it's supposed to take you to the read me page.
Now if I get the R L for a certain repository and I want to view the read me there is a segment that
goes after the u r l.
Every single time and that makes it easy for us to load that up.
So lets just type let read me segment and that is equal to slash blob slash M. slash.
Read me M.D and for every repository it may not be exactly the same and some repositories might not
even have read me.
In that case you'll just get a 404 error on get help when you're looking at it on your phone.
But for the most part I would say 99 percent of the time they're going to have a read me in this exact
same format so that is what you can do.
Now if you wanted to just make this save you repository great they could click on that and it could
just show the repository.
But I think it's cool to be able to view the read me because that's where most of the good information
is anyway so this is great.
These are are you or else we can use this in our download service.
So let's go ahead let's create it now.
Right click on services click new file and we're going to go ahead and just create a swift File.
We're going to call it download service and press create.
Now you've heard me use the word Singleton and a singleton class is basically a class that is going
to be publicly accessible by any and all classes in our app for the entire lifetime of the application.
So as long as it's running that class is available.
So we're going to actually create it now by typing class download service.
OK.
And in order to create this into a singleton class we need to create an instance of this class inside
itself using what's called a static variable or static constant.
So go ahead and type let instance wups instance equals download service and instantiate it.
Right.
We're creating an instance of this class inside itself.
But if we want it to be accessible for the entire lifetime of this application we need to start it with
static.
OK so it's a static constant.
And I don't know if it'll actually give you information on why we're calling this static here but any
way you can look it up.
Basically what static means is it turns this instance into an instance that is going to stay in memory
for the entire lifetime of the application.
So now if we wanted to access this from anywhere we could just call a download service instance and
we have access to everything that's going on in this class.
Really really cool.
Of course you don't want to abuse the singleton pattern it is possible and people do it.
So let's go ahead and let's start by writing our first function and we're going to actually call it
download trending repo's dictionaries array.
It's a really long name but you'll see why in a second.
So go ahead and type phunk download whip's rending repo's dictionary array.
All right.
That's a really long name but basically the Jason that is downloaded in is an array that is full of
dictionaries each repo comes in as its own dictionary and the Jaison that comes in basically parses
it into an array that's full of dictionaries so we can access a dictionary at a certain index in the
array which is pretty cool.
It's a little annoying to have to cycle through all of it but I'll show you how we do it.
So in order to actually return values we're going to be using a lot of nested closures.
And since we're using closures we're going to go ahead and need to use a completion handler to return
the values.
So go ahead and type completion and it's going to be escaping.
And if you don't know what escaping means basically if you have an escaping closure it allows for values
to be passed in and then they can actually escape out of the closure to wherever this function is called.
It's sort of like returning a value to a function except it lets us do it out of a closure.
So for this escaping closure we need to actually pass it a function and it's going to just return an
empty function because we don't care about the return necessarily.
We do care about what gets passed into this function because basically think of this function like a
like a black hole.
We can pass the values in through it and then on the other side wherever this function is called we
can access those values.
So we're going to go ahead and use repots dictionary array like so.
And just like that it's going to be an array like we said of dictionary and the dictionary is going
to be of type string and any it could come in as a string could come in as an integer any value so we
don't want to have a crash just because we get a value that we don't like.
So any is the way to do it.
Now we're getting an error and it's saying function types cannot have argument labels use underscore
before repots dict array.
OK so we can't use a name for whatever reason Swift doesn't like it.
So we're just going to use an underscore just so that we can see this internal parameter but you know
switch is not going to let us use that as a parameter for whatever reason.
We'll have to ask the swim team why that is.
But anyway so now what we can do is we can start doing our downloading which is really exciting and
to do that we're going to need to use Alamo fire.
That's one of the libraries that we installed.
So go ahead and type in port Alamo fire.
There we go and Alamo fire is going to help us to make network request and download stuff really easily.
So let's do it.
Let's go ahead and type Alino fire request.
And as you can tell we can pass in a convertible which can come in as a string which is really cool.
So go ahead and type daat request and for the you Arel we can pass in our constant trending repo.
You r l we just created that and our Constans file appear.
So pass it in and then basically we are making a request.
Now we need to think about what are we going to do with that request.
We want it to come in as Jaison.
But watch what happens if I type dot response.
You can see we can get it as a response with the completion handler response as just raw data response
as Jason ding ding ding response string response property property list.
We can get a lot of different types but we want Jason so go ahead and click on Jason and then for the
completion handler we just need to press enter and the property here this is the response.
This is the Jason data we're gonna get back.
So I'm just going to go ahead and just call that response.
That's just the property name I'm going to use for it and we're going to basically now create a constant
called Jaison that is going to be set to the value of whatever response this is.
So let's go ahead and let's use guard Latt because when dealing with network quest you want to be extra
extra safe because not all repositories are going to be the same.
Some may have some data that another does not.
Each repository is going to have required data but some might have more than another and in order to
avoid crashes we want to make sure that we are optionally casting things when we can just to make sure
it's safe.
So go ahead and type guard let Jason and Jason is going to be equal to response.
Oh you know what.
I spelled that wrong response.
There we go.
Response.
Result.
OK and then from the result we're going to pull out the value k which that's going to bring that wrod
Jaison data.
So we're going to need to cast this.
Like I told you as a dictionary of string.
And any.
OK.
Now since we're using guard let We need to give another condition in case we cannot get that value.
We're going to type else and then we're just going to return because this function does not require
us to return anything.
So we're just going to go ahead and return get out of the function and keep us from crashing.
Now you're wondering why is this coming in as a dictionary of string.
And any and you know what.
If you remember when we made a call to the API and let me pull that up here.
So here you go.
As you can see when we make a call to the API it actually comes in as a dictionary first I think I misspoke
earlier.
It comes in as a dictionary.
But what we need the important stuff is in items and items happens to be an array of dictionaries.
There's one dictionary and later there's another dictionary.
And so it's in a dictionary that contains an array of dictionaries so as you can see it can get kind
of complex kind of hairy fast so we're going to go ahead and just cast the initial Jaison library as
just a dictionary of string and any Then later we'll pull out the individual array that's full of dictionaries.
But for now let's just see how we did.
Let's go ahead and print.
Print the Jaison and this will just basically let us see if we're downloading the data properly.
But we need to actually call this from somewhere.
Right.
So let's go ahead and let's just go to trending feed Visi and when the view loads we'll just call a
download service instance that's how you access that singleton class.
And then we can call download trending repo's dict array.
On completion we'll just.
Well you know what.
It's actually going to be returning something to us.
Let's just go ahead and just say Jason guys we're going to delete this and fix this in a second we'll
just print done downloading and now we're calling it which is good.
We'll delete it in a second but let's just go check to see if we're actually successfully downloading
all of our Jason data.
And this is the hardest part guys.
After this it's basically just writing little functions to do the custom stuff that we want to do.
And hey look at that.
I see Jason there's all of our Jason data from the API.
Obviously that's way a way way way more than we want.
But check it out.
So we're getting an array here and we're printing out our Jason.
There's the first dictionary all of the you are Elle's the fork's count.
We get the full name.
We get all that cool data.
That's exactly what we want and you notice we're not yet getting this done downloading printing out.
That's because we never called our completion handler so we're not handling completion but we are definitely
on the right track.
We're downloading all of our Jason data and now it's just a matter of parsing through it and creating
the proper repositories that we need.
So let's go ahead and let's actually close the console there.
Stop the app from running and let's go ahead and clean up what we just did.
We don't want to call that because we don't need to.
But guys that is awesome.
So we are getting our Jason data now.
We should basically pull out that item's array of dictionaries.
So let's go ahead and let's create another guard to do that.
So type guard let repo dictionary array because the Jason is not only repo dictionaries.
We're going to go ahead and set dictionary array to be equal to Jaison.
Now remember it's a dictionary.
So in order to get the value we need to pass in the key.
So go ahead and put some brackets there.
And the key as you know is items right.
We saw that and what we can do is we need to actually cast this as the type we want because we know
that items is an array of dictionaries so we can cast it like so array dictionary.
And it is an array of string whip's string and any K just like that.
But we are using a guard.
So we need to provide another condition if we can't do that then we're just going to go ahead and return
K and it is just common to put two spaces on either side.
But now we have a repo dictionary.
Now we're not doing anything with it but we are getting an array of dictionaries.
That is exactly what we wanted right.
We have our training repo's dictionary array.
So we now have the proper repository we have it exactly how we want it.
Now all we need to do is somehow find a way to pass it back to our function.
Right we need to pass it back to our completion handler.
So what we're actually going to do is create a variable at the top of this class and then at the bottom
after we have created this dictionary array we're going to pass it in to our completion handler so that
when we call the function we can access it.
So let's create that variable now go ahead and type trending repots array and it's going to be an array
of dictionary of type string and string and any K.
And we're going to go ahead and instantiate it from the get go like that.
And now we have an array that we can set the value and we just created that right here right.
So what we can do is we can go ahead and set trending repots array.
And that's going to be equal to repot dictionary right.
Pretty easy right.
So this is great and all but we need to think we're actually returning like all 800 values.
All eight hundred little dictionaries in here and I don't think we want that many.
Maybe we should just display like the top 10 values.
OK.
So let's go ahead and actually get rid of this first and we can cycle through our repo dictionary array.
And let's just keep track of how many items are in this array and once we reach a certain number then
we'll break.
So let's just say if we all know let's go through the array first four repo dictionary in Ribault dictionary
array.
And if the trending repots array count is less than or equal to 10 k so we're going to just say we're
going to stop at 10.
Let's go ahead and let's just say trending repots array dot append and we're going to append the repo
dictionary.
OK.
So that way it will stop.
But let's decide what it does so if it gets to 10 it's going to append.
And then once it's over 10 it's not going to append anymore so we need to say else and we need to break
out of the function basically just stopping the for loop from running.
Oh sorry I didn't break out of the for loop.
Stopping it from doing its thing.
Then at that point after that for loop is finished once we are completely done with our Alamo fire call
downloading all of our data.
We are done what we can do is at the bottom call completion.
And then inside of our function look at that it's asking for an array of dictionaries we can pass it
trending repots array because we have filled it with 10 items.
Kate that's super easy.
Now let's go to read and let's call it again let's see if we get 10 repo's and let's go ahead and just
double check that everything works so call download service from trending feed VCs view and load instance
download trending repots dict array.
And we're just going to call this repots dict array.
All right.
And let's just say print.
We're going to print out the repo's directory.
Sounds good.
There we go and as soon as it's done downloading it should print right here.
OK let's check it out.
The app is loading the console is coming up.
Are right.
So it looks like we're getting nothing looked at it printed out an empty array.
So that's not good.
Let's go look to see what the problem is.
So it appears that we are cycling through K we go through here for Ribault DECT in repo dictionary array.
If the count is less than or equal to 10 which it starts out as zero.
So of course it is.
We append it and then we go through again we we appendant go through again until it gets to 10 and then
after that we are going to go ahead and call completion.
Oh you know what.
Alamo fire is a closure.
So we we never tell it within the closure that we are finished.
We call it afterwards so that is part of our problem.
Basically we need to still be inside the same closure block to tell it that we're done because it never
knows when we're done because it goes inside this closure and it can't get out.
It's kind of like a trap.
So let's try that again.
Let's build and run and let's see if it'll properly call our function it's loading.
There we go.
So we're getting all the data and it looks like now we only have 10 10 items coming in because let's
see if we have one.
There we go it's hard to find the end of one and the start of another but I can tell for sure this is
a lot less data.
So we're starting with Apple's Swift which is obviously the highest and we are ending with one that
is pretty close but pretty much lower.
But yeah guys look at this.
This is awesome.
We are downloading our trending repots data.
We're returning them and we get a nice dictionary.
So let's go ahead and let's let's delete this.
We're not supposed to call it here.
We're going to call it in our download service later.
But guys we are downloading all of our repository dictionary data.
This is amazing.
In the next video we're going to do is we're going to actually create a function that will download
individual repo data and then return an instance of our repo model so that we can set up ourselves.
Very very cool.
Let's head over to that next video now and let's do it.