Hey what's up everyone.
Mark Price here at the slopes dot com and we're making fantastic progress on our application here.
Coder's way up.
And what we need to do now is actually feed it with data.
Now like I said normally you would have an application hit the Internet a server and Dallas and that
day.
We don't have a server right now.
But on the flip on the opposite side some apps don't actually do that.
They actually have the data hardcoded with the app because there's a limited data set.
Or maybe they don't have a server and they're just doing a few limited things.
This might be like let's say you're building an app for a law firm or an app for a local business where
they only have so much data and they're not going to probably update it a lot.
Well that's our case right now.
And so we're actually going to build the data in the app.
There's nothing wrong with that.
It wouldn't probably be the reality of what you're doing because you're you're probably talking to a
server when you're building up a storefront but we're going to build out our data model just like as
if we're downloading it from the Internet and we're going to do it here in the app and that's what we
might actually do for if you're running an app for a local business that doesn't need continuous data.
So it's a win win all around.
So let's go back to our going to stop it from running just to make the computer run a little bit faster
here.
And so we know it's running but we also know that it's not feeding data from where it needs to go.
And so I already know that we're going to need some type of model soon to be a reusable class or struct
that can feed our table with data.
So let's go ahead and create a new folder here.
Next it will before we do that let's create the model itself so I get to go to the model folder in a
new file.
Inside this model file We're going to switch file and what we're going to do is we're going to call
this the category.
So basically I'm creating a category that's a reusable struct.
In our case we'll use a struct.
OK.
This looks good to me.
And so we're going to say structure and we're going to call this category.
And what we're going to do is we're going to create a couple of variables one for the variable for the
title and a variable for the image the name of the image that's in our that's in our assets folder right
here OK.
We need to grab these names we need to feed those into the table so the image you knows which file to
grab.
OK.
And so we're going to create an array of categories that stores that information.
OK.
This is exactly what you would do if you were downloading data from a server and then parsing it you
would create some type of model or class that can be recreated over and over and store that data.
OK.
Okay so first things first is let's go ahead and create our title in our image name so public var title
of type string.
In fact let's be more explicit.
Well here's another Here's another topic of discussion.
We could say category title right.
But maybe that's a little too explicit because the struct itself is already category so we know we know
that the if we said just the title that it's the category title since we already are named it category.
Why repeat yourself right.
So I think it's ok actually in this case to just say title.
All right.
So me of type string and we're not going to make it an option or implicitly interrupt optional we're
going to make sure the data is there when it's initialized so we're going to leave it like so and then
let's do another public var image name of type string as well.
OK.
But I think there's a problem here.
I don't think it's good practice to keep these public.
OK to just let anybody set these things.
OK well what I'm saying is you know if we create a category if I was to create a category like this
and this is public titles here and let's just right now just for sake of demonstration I'm putting the
exclamation marks there.
And if I was to go into categories B C and let's say I wanted to create a category so I said let cat
equals category like so.
OK then I guess a that tidal pools.
OK.
That's typically not a good practice.
You don't want to be able to just set public variables for anywhere.
And the reason why is because you want to control the data that's in your class you want to you have
the creator of that class or that struck.
You want to control how it's accessed because you don't want anybody shoving junk data into here.
OK and it's probably hard to understand right now but that's OK.
Just take my word for it that we want to protect our data a little bit better.
So what I'm going to do is delete these examples here.
What I'm going to do is go back to my category and instead of making these public what I want to do
is a private sit on these here private and so and what this means is I will no longer be able to set
these variables to other classes ok or from a view control or things like that I can retrieve them and
use them.
But I can't set them and I think that gives me better control of the data that's in here.
I don't want any you know so your buddy who's a programmer comes in the app and doesn't know what he's
doing and starts setting up the wrong titles and hear things like that and you can't really control
it.
But if you design your struct or your class in a way that that serves your application the way that
you want it to and protects it then you can be sure that it's it's acting as needed.
And again you don't have the complete understanding here.
But the rule of thumb here is you want public variables that can be fetched but you don't want them
typically to be set by outside classes unless that's what your app calls for.
OK.
So what we're going to do is create an initializer here.
All right we have the title the image name.
Now these are parameter names.
OK.
You typically name initialiser parameter names the same as this is this variable the same as this.
Absolutely not.
We're going to pass data in.
And then even though it has the same name we're going to set it up here to this title here.
It's just a good convention to make these the same names as the variables that you want to set in your
initializer.
And so we're going to say self-taught title Beatles title and self-taught image name equals image name.
OK so all we've done so far is we've created a struct called category.
We created a couple of variables that are public for fetching forgetting but they're private for setting
outside classes and structure etc. can't set them.
However when you're creating it from the beginning when you create a new category that's when you can
pass the data into these variables here.
And we are in complete control of how data is getting into our struct here.
And so we're seeing self-taught title self of course is referring to this this class or struct itself.
OK.
So we're saying this title here is going to be equal to the one that we're just passing in and this
image name here is going to be equal to the one that we're passing in.
OK.
So now we've got our our category struct and a little bit data here a little bit of data protection
which is great.
And what we're going to do when we're going to say is just from now on even if you don't understand.
Just do it this way.
OK.
Make it private for setting and public for retrieving and it'll save you a lot of headaches down the
road.
If you didn't make it public all together that's fine.
But I just wouldn't recommend it.
Can we do this in our apps.
So next thing is we've got this data here but how do we actually create a list of data a list of data
to feed our table view with.
And we don't have that right now so what we're going to do is we're going to create what's called a
Service OK and a service is a design paradigm in programming.
It can perform functions for you or provide a service.
It is what you think it is.
And you know similar to you might call a plumber service or an electrician service they'll come and
do a service for you don't own it.
You know you don't you just ask them to do something and they do it for you over and over again.
And that's the same thing that we're doing here as a category.
You create multiple copies of a category OK.
You're creating something over and over and over again whereas a service does things for you.
And so our service is going to store some data and it's going to perform it's going to send us the day
that we need more or less.
So could a new folder or new group we're going to call this Services.
I'm going to put a new file in here.
And it's just going to be a swift file and I'm going to call this data service OK.
And what we're going to do is we're making this class say class data service like so and then we're
going to say static let instance equals when say data service.
OK.
So this might be confusing to you but what we've just done here is the key term to remember what we've
just done is we've created a singleton.
A singleton is another design pattern.
And this is the this is the idea behind it.
So you know the class or struct that's how you would typically use it is you would create multiple copies
of over and over and over again.
Well what we've done is we've created a variable here ok called instance that's what we'd call it.
It's a constant actually.
And we've created a brand new copy of the data service.
But guess what.
We've made it static.
OK.
And what static does is it means there's only ever one copy in memory so you can only ever ever ever
create one data service.
OK.
And that's what we want we want.
One copy in memory because this is going to hold our data for the app.
You wouldn't want 10 different copies of data service all holding different versions of the data the
way your app would be broken.
It would have inconsistent data and bad user experience.
And so by specifying a constant here called instance and then immediately initializing a new class a
data service.
Every time we go in and grab this instance it's going to refer to the exact same object in memory which
is what we want.
Again you don't have to completely understand this but typically when you write a service and you need
to do something for you over and over again you can make it a singleton.
The caveat with singletons is it's there's one copy in memory so if we create this in memory from the
beginning of our app OK it's probably going to be there for the entire life lifetime of the app.
So if you need to save memory.
OK.
You don't want to have a bunch like 100 different singleton class is doing a hundred different things.
OK because your app is starting to take a memory that will never be reclaimed because there's always
one in memory whereas when you create objects and Strax you know those things get cleaned up when they're
not being used anymore.
This will stay for as long as your app is living unless you manually destroyed it somehow.
So I know that's all a bit wordy and there's a lot to go over there but we've just created our instance
here.
And what I want to do is I want to envision what that work table is calling a function that's hitting
a server and it's retrieving data.
Now in our case it's not going to do that but we're going to simulate that.
So I might have a function here called Get categories and we'd go to the server OK and we would return
a we would get a list of categories and then feed them into our app.
And so let's go ahead and actually create that data source let's say that this is our data source from
the server so private let category.
And we're going to create an array filled with data and so we're going to do is we're going to create
a category and knows how it needs a title and an image.
OK so what we're going to do is we're going to pass on a title so we'll say shirts and the image name
is going to be shirts stuffed PND but a comma here because we're just we were pre populating an array
with data.
So the next item in the array we're going to create a new category.
And again you're starting to see multiple copies of an object.
So right now these two categories it's going to create two copies of this struct and it's going to hold
them in different places in memory.
OK.
Whereas the singleton only has one.
That's the difference OK.
In one case we're creating something in another case we're using a service over and over again.
So hoodies.
Image Name hoodies that pinchy.
Now again if you're confused or like Mark how is this real use case.
Well if you have an app where you want to heart get all your data in the app.
Let's say you're a new developer and you have an idea you're not ready to talk to a server yet or your
app small enough you can actually do something just like this.
You can put all your data here in the app and feed it into your table to use things like that.
If if you weren't doing it locally you want to hit a server OK.
You might still do something just like this you'd hold an array but instead of creating them here at
initialization time it would come from the server and then it would populate the array.
You know we would say category's equals and the new array from the server.
So not all that different category title and this one is going to be this image name as hats that PMG.
Now I know these these are the right image names because I drag them in.
And as you can see we've got digital hats and those are PNB files OK.
And the category title An Oregon State Digital and image name is going to be digital.
TNG like so.
OK so now we have a list of categories This is great.
And what we've done here is we've inferred the type of the Saray what we're seeing as categories is
an array of type category.
OK.
So when I say returned cat or good categories the return type is going to be an array of type category
like so.
OK.
So what we're saying is that we're going to return to ever calls this function and array of categories.
OK.
With the official category struct and this is not accessible.
We made it private because we don't want anybody accessing that data directly we want a function here
in case it needed to do any cleanup or manipulation.
But what's really happening here is you know we're simulating we're hitting a server and we're turning
data and you would do that through a function and then all we're going to do in here is a return category.
So we're going to return this array to whoever calls it.
And because this array is a type category this will go away and we are in business here.
OK.
So a lot to cover right.
It's a lot of information.
But our app is really coming together it's looking nice because some good data in here and of course
this is the importance of working with structure clauses that you can make reusable objects.
You write the code once and then you can use it over and over and over again.
OK.
So here in our view controller we've got a table view.
OK but the table you is not being fed with data yet.
So in order to get this working properly we need to introduce something called protocols and delegates
done it new words new things Ziller.
No my head's going to explode already Mark.
Just make it stop.
Sorry.
You're on a adventure of brain explosion and it's going to keep going until the end of this course and
for the rest of your life as a programmer.
Sorry.
OK.
So we got a tape of you how do we feed it with Dave.
Well a table view it needs to know where the data source is hey I need some data.
Give it to me where do I get it.
And also there's other things too it's like hey I need to show cells on the screen.
I need to show something on the screen and fill it with data so that you can have something to look
at.
Well it's not doing there now.
So let's go ahead and do that.
And we do that by implementing some protocols put a comma after you have your controller or table you
data source and you table you delegate.
OK.
These are two protocols.
And even though it says data source and so delegate these are protocols a swift protocol and they're
really based actually on Objective-C the code was written long ago but in swift they're translated as
protocols.
And so these are protocols and swift.
And what we're saying is we're going to abide by a set of rules and we'll talk more about protocols
later in more depth and detail.
So just follow along for now.
So you I table your data source in your table you delegate Kesselman to save this file here.
All right.
And normally these would yell at me.
All right.
Here we go.
And so if we click this little red icon here new with X code 9 is to actually populate the functions
that you need to get this working.
So click that little red air and it says type categories.
VC does not conform to protocol.
You idea will be datasource.
You want to add protocol stubs so what is saying is you're not listening to the rules.
You adopted a set of rules table your data source and you will be a delegate but you're not abiding
by the rules you haven't even implemented them yet.
So I'm going to click fix just great and it put them up here which is kind of annoying.
So my command X and what we're going to do is put them down here and we're going to do some cleanup
here.
As if the current X code version which is beta it shows you know this available etc. etc..
That may go away in future versions I would expect it would cause it's kind of messy and ugly.
But get rid of the available as well too.
And it's available here.
So it's implemented the two functions that it requires in order to operate correctly.
OK.
Number of rows sections or how many rows do you want the table view to show you need to know that in
advance and then sell FERO index path.
OK sell Pharo at index path.
And what this is saying is hey let's create a cell a reusable cell.
At this particular path.
So item number 10 show the cell and put this type of data.
This is where you actually feed the data into Table View item number one or two or three or four etc..
Ok so how many rows are in the section.
Well this is pretty easy.
All we have to do it wants an integer and we just want to know how many table view roles we already
know that it's what four we have four on the screen.
Now we could just see it returned four but that's cheating and that's not the way that you would write
code.
Real code robust code.
So we're going to return data service that instance we're going to call that instance function on it
OK or that that variable.
And then we're going to call the function get categories.
OK so what we're doing is we're grabbing the categories.
Well what is category's return when it returns an array.
So we know that we're getting an array right here.
Well this is asking for an.
So how do we get the total number of items in an array.
Simple.
Calling the count function.
OK.
So what we're doing here is we're saying return the total number of items in this array.
OK.
Easy enough.
That's all we're doing we're turning a count.
But what about this guy.
How do we actually grab a cell and put data in it.
Well I think we should write some code in our table cell first before we actually implement this function.
Here's what we're going to do is we're going to go over here to our view or category so what I want
to do is delete this function sets like that don't need this and I don't need this away from the zip
file or.
Right here we're going to create our own function here.
Or to call this update view.
OK.
Basically update the views on the cell and we're going to pass in the category.
Whatever the current category is.
Okay.
And again this is another reason why you should have had reusable things.
Otherwise we'd have to have a title here an image name here and we'd be passing two different items
and over and over again in this case we're only passing one reusable object which is well-written code
and protected.
So we're an updated use basically every time we want to show a cell on the screen.
We're going to call this update use function and pasand a category and it's going to update the views.
So let's show you how easy this is here.
OK.
So we're going to say category image image.
So we're going to set the image on it equals UI image and we're going to do the one that says image
named and all we're going to do is pass in the name of the image that we set in the category so category
the image name.
It's that easy category inch or category title.
The next one text equals category Dopp title.
We did that as well to remember our category here.
It has an image name and it has a title.
Amazing.
All we have to do is grab what we've already set right here and it's as simple as that for an update
that we use every single time.
Easy peasy.
OK.
So let's go back to our categories of now and how we can implement this function down here.
Let me give it a little more space so you can see what we're working on here.
Let's close this.
So here in our table view what we're going to do is say if let cell try and create a cell equals table
view dequeue re-usable cell with identifier we have not created this identifier yet.
So we're going to assume it's name we're going to call this cat a category cell.
OK.
And we're going to cast it as a category cell.
So what we're doing is we're grabbing we're grabbing the table view that is working with this with this
delegate and we're calling dequeue reusable cell.
And this is the function you call to get a reusable cell did you know on a table view on us.
OK in a similar with Android slathers one two three four items visible.
Did you know that.
Let's see if you had 100 items they would not be under here hidden there would only be probably five
or six cells altogether.
And what happens is it takes the one off the bottom that's no longer on the screen and puts it back
on the top so it grabs the item still in memory so it doesn't have to recreate it and slow down your
app and it just hey I got a new I got your old cell for you.
What data should we put in it to update it.
That's all.
What.
Yeah.
It just grabs an original cell you've already used and you update it with new data.
That's how it works.
So what we're doing here is we're grabbing a reusable cell.
OK.
Called category cell which we have not set yet and easy.
Now all we have to do is grab the category for this row and then put it in the update View's function.
So when you say let category how do you think we can grab the appropriate category or what I want you
to do OK on your own pozires video that I want you to figure out how to grab the proper category for
the proper row and store it in this variable.
Did you do it I know some of you did and I know some of you didn't because that's how it always works.
But for those who did congratulations.
You know if you figured it out if you didn't.
That's OK because we're going to do it right now.
So let category.
Equals.
OK.
You ready.
We're going to see data service that instance get categories.
How do we get the right category at the right row.
What do we do.
Well we just grab the item from the array index path Dutrow.
OK.
Does this look really funky to you.
OK.
You're like what's going on.
This is Grady's index.
When you were teaching a phrase you never taught us to put square brackets after parentheses that doesn't
make any sense to me.
Well it's because we're returning an array from a function.
So this would be the equivalent of doing this I could have said Let lead categories equal data service
instance get category.
So it's stores like you know the the array inside of a category.
Here are the categories array and then what I could have done was I could have just you know I could
have set categories like so.
OK.
All that's certain look familiar to me now because that's an array and you're grabbing an index out
of that array.
But why do that when we can do it so much more quickly with one line of code.
So grabbing the categories and there were grabbing the specific item out of that category.
Easy peasy.
OK.
And if it's not easy Don't worry it just takes lots of practice.
OK.
You'll get this down over and over again.
Code repetition code every day study every day.
Let's go ahead and update the cell now so cell that update views.
And it's looking for category.
So we passed in the category that we just grabbed.
OK.
And that's looking really good as well too.
Now a lot of developers are really tempted to do some nasty code that goes something like this instead
of just updating views and letting the view manage itself.
They like to do things like this like that.
Like the say cell dot image the dot image equals you know category dot image name.
So the same thing we did in our view but they like to do it here from the tail view and that's bad practice.
You always want your views to be self-contained.
You should manage themselves.
The controller should say what's going on the screen at different times but every view that you have
should manage itself.
If it's of any consequence or significance which a table you sell is so don't ever do this don't ever
manipulate your table use cells from within your table view for an index path it's nasty and it's nothing
I teach.
And if you learned it you didn't learn it from me.
So do it this way it's much better.
All right and so what we're going to do next is return that cell because the function table view self
wrote next path it wants us to return a cell.
Else let's just return an empty one return category cell like an empty cell like so.
Are you with me so far breaking really good progress here.
We've got our our delegate function implemented well.
Suffer index path and number of rows in S..
One other thing we need to do is set the data source and delegate of the table view.
So we're going to say if you did load categories table that data source equal self category table delegate
equals self we're saying is hey the data source is this class this category.
VC view controller self.
We're assessing how the data source is also this Self.
OK.
If I took these off we would get an error here because it's like what's going on.
I don't this doesn't make any sense to me where you're sitting these delegates.
You cannot assign value of categories to type you if you data source because it doesn't exist.
But once you implement the protocols OK and those properties do exist and you're setting the class you
set into class on them.
So OK this class itself category b c this view controller.
So that's looking good.
We need to do a little more clean up here in our story board.
We've used this category cell identifier for the reusable cell but we actually haven't given it a name
an identifier in our storyboard so let's go back to the main storyboard.
OK.
Click your cell category cell and open up the right hand side here and we're going to go to the attributes
inspector and see this reuse identifier.
This is where we're going to type in the we go.
We're going to type in the category cell that's the name of the identifier that we wrote in the code
and it has to be the same.
And a lot of developers get this.
They forget this spot right here and they bang their heads.
You have to do this.
You don't put the identifier it doesn't know how to reuse the cell.
OK rookie mistake Hogan.
Let's run it and see if it works within a lot of talking.
We haven't actually read it and see if it works.
OK.
So it looks like we have an error did not work.
So a category table that data source equals self.
And it says it's Neal This would indicate to me that somehow we lost our category table connection in
Interface Builder which seems strange to me because we set it Melissas double check anyway.
I also noticed that and in turn Eric heard editing functionality may be limited.
This is currently a beta software and so it could have bugs as well too.
But it shouldn't be a big deal.
Let's look at our table view OK.
It looks like our connection was lost which it is.
Let's reset here.
Category table to the table you get all I'm glad you saw that.
That's a good way to know when something's wrong.
Mark how did you know that it wasn't there well it was said it was nil.
It said the table view that delegate was nil.
Well I don't think it could be is it wasn't it.
It wasn't in memory wasn't even created yet.
OK.
So it's not working clearly.
So we've got no cells here showing on the screen and it's just blank.
So we should fix that.
Let's go back to our code work reducing debugging
the right hand here.
Oh yes another rookie mistake which US long term developers still make is we didn't set the outlets
on the table of you so was going to in-store board and it's click the sell here or we did and it it
deleted those as well too.
Which is also a possibility.
So category so right click it you know are used aren't even available here.
I think our tax code hosed them.
So let's go back over here and look at that.
We lost our class as well too.
So I clicked the identity inspector here.
OK.
And I'm just resetting the category so somewhere in here X code chopped up our stuff.
So that's why it's not working.
All right now if I right click category sell you'll see the category image and the category title.
Perfect.
OK this is good too you're seeing debugging real time problems that are happening.
Mark why.
Why is this blank.
Well I'm thinking in my head the only reason why I could be blank is if the views are one is the data
is not there but the data is there we've written that code.
Or if the views aren't connected which they weren't.
So there was one or two possibilities.
So let's run it again and see
and there we go.
It's not perfect but you know what is cool.
You can actually scroll a couple problems I see here is these are supposed to have a little bit of spacing.
So let's fix that and let's get rid of this ugly scroll.
I always hate the scroll things on the sides and the bottom so let's fix those as well too.
So how would we fix this how do we create spaces between cells.
Well you really can't.
You can't create a spacer between cells.
What you do is you simulate that space using other means and methods that you already know how to do.
So what I think we're going to do is just add a little more padding causes lift inside a little more
padding on this image itself here.
So in this category image what we can do is just bring a little in from the bottom here and the top
probably.
So let's look at our measurements here.
So we've got this bottom space and top space.
You know what I think I want to do is delete these and the top space and we'll reset them.
This is faster that way.
So click the pin menu.
And what I'm gonna do is I'm going to say three from the top.
And three from the bottom.
OK.
So three from the top three from the bottom bring it up a little bit there let's run it again and see
how it looks.
I didn't put more than three because if you put top on the bottom three would add up to six and would
give it more spacing so I'm just trying it out with three DCO looks as good as these ugly lines in between
which I definitely don't want.
So let's go and get rid of those and that's really easy.
All you have to do to get rid of those lines is click your table view itself category table.
OK.
Could the attributes inspector and see the step the separator how it says default.
Change it to none.
And then let's run it again and see how it looks
wonderful.
OK this is kind of looking like the image here but not very much code.
I think our text is like black and should be dark gray but I don't care.
I'm not going to tell the designer if you don't care.
This is looking good though.
So what we've done here is we've set images dynamically as if we got them from a server.
We also set the titles of those cells that are dynamically as if we got them from a server somewhere
and we're repopulating data and then when you know hypothetically when shirts and clothes and things
products would change on line they would change your automatically which is really cool.
So this is looking good.
One more thing let's get rid of those ugly scrolling things.
So click your table view here and let's go to our scrolling.
Let's take up the scroll indicators there called scroll indicators.
I don't you know I don't remember the name because I don't want to think about it.
OK I take both of those off.
And this is good.
We're good here so we're going to get this video done we've done a lot.
OK we've done a lot.
We've created a custom table view cell.
We pass data into it we implemented delegate functions.
Ok this is great here.
We've implemented delegate functions.
So remember you implement a protocol and then it calls delegate functions so protocol has a delegate
or something that represents the protocol.
You'll learn more about this and then delegate X on its behalf.
In our case the delegate was the category's VC and so we implemented cell index path which basically
dequeue is a cell.
OK.
And then it makes it reusable and then you update the data in it.
OK we said an identifier on here and in this.
And we said how many rows we want to show all together.
OK.
So the delegate and the datasource here of the table and we connected Iby outlets and we did some debugging
to X code just hosed all of our wonderful work.
We knew exactly how to fix it.
So a lot of good stuff here you may have to watch us over and over again.
But when I'm programming I was to build it professionally and on the slopes.
There's not a day that goes by where someone on her team is not working with table views and doing this
exact type of code so that's it for now.
Mark Price a slopes.
Let's move on and board.