Hey everybody this is Caleb with slopes com and in this video we're going to set up a model layer in
order to create messages which of course as you probably know a message has to have content words and
it should have a way to identify the sender and in our case we're going to use our unique ID.
So we're first going to create that message model and then after that we're going to create a function
that's going to download all of the feed images that's going to download all of the feed messages from
firebase and then we'll set it up to display in our table view really cool stuff.
So pull open that XCode project and we're going to start by creating that message model by right clicking
on model and creating a new file.
Next.
Go ahead and type or select a swift file and we'll just call this message press create.
And now we're going to create our message class.
So go ahead and type.
Class message and now we need to think every message needs two things content and a way to identify
the sender.
In our case a Sender ID so to do that we're going to create some properties to hold just those things.
So we're going to use data encapsulation like before.
So go ahead and create two private variables private var underscore content of type string.
And we're also going to type private var Sender ID of type string.
Now we're going to create two public variables for the same ones but remove the underscores and set
these ones to be able to display the proper information.
So go ahead and type var content of type string.
Get some curly brackets and we're going to just return the value of content.
OK.
Now go ahead and call var Sender ID of type string.
And we're going to return the Sender ID.
Now we're going to do is we're going to set up an initializer so that whenever we want to create an
object of message we're going to initialize that message with the proper content and with the proper
Sender ID.
So go ahead and call in it and the parameters we're going to pass it.
One our content of type string.
And guess.
Can you guess I can guess its sender ID of type string.
So when once we initialize this object with content and ascender ID we should set self datt content
to be equal to content and that will basically give us the ability to access this content variable because
we can privately set the value of content here but nothing else can and our and our app only through
our initialiser Can we set the value of content and then the public variable content can be accessed
by underscore private variable content.
So its a really cool way to encapsulate the data and hide it so that it's only accessible by the classes
you want it to be accessible to.
So self-taught underscore Sender ID is equal to the sender ID we pass it at initialization.
That's it.
That's our message.
Class it's super duper easy.
And now we can actually create a function to pull down all of the message data from the feed on firebase
pass all of the information into an instance of message and append that to an array of messages that
we will then display in our table view.
It's really really cool stuff.
So let's go back to our data service and let's write a new function below.
We're going to call it get all feed messages so go ahead and type phunk get all feed messages and we
need to think about what we need to do.
We're going to call or we're going to try to pull data from our feed reference and we're going to pull
it down when we're all the way done.
We need to be able to pass the data that we download out of our closure and the only way we can do that
is through an escaping closure.
So using a handler like we have been using is a really great way to do that.
So let's go ahead and let's call handler and it's going to be escaping.
And then what we're going to do is we're going to create a function and this function is where we're
going to pass in our values.
Now we're going to call messages and remember we're using an underscore because you're not allowed to
use parameter names on function types.
So we need to use that underscore there so it doesn't have an explicit name.
But what we can do is we can now use our model layer to return an array of message.
Very very cool.
So we can pass that message back to our view controller and then load it up in the function.
Now of course to use a handler we need to basically return something.
But in this case we're just going to return an empty function because it doesn't really matter what
we return.
We just need to pass these values into the functions so we can access them on the other side thanks
to it being escaping.
So go ahead and build and run make sure that error goes away.
Looks like it does now.
Let's go ahead and let's dive in to the feed.
So call ref feed and what we're going to do is we're going to basically observe a single event when
this gets called we're going to download every message from the feed array.
So go ahead and call observe single event and I'll explain while we're at why we're doing single event
instead of just observe later.
But for now we're going to observe all the values in the feed array.
And next we're going to actually use data snapshot here to pull down all those values so press enter
and we're going to call this feed message snapshot and I'm actually going to copy that name.
It's a little long.
So that's great.
We just pulled down our we observed everything in the feed we downloaded its value and we saved it into
an array of data snapshot from firebase.
Now we're going to use a guard left to create an array of data a snapshot and we're going to use guard
let just to be safe just in case a value did not come back.
So go ahead and type guard let feed message snapshot.
I copied and pasted that equals feed message snapshot this one children.
All objects.
OK that's going to pull all of the objects out of the entire feed so if there was 100 messages we would
get 100 objects.
And in order to actually properly do this we need to cast it as an array of data snapshot that comes
from firebase.
OK.
That's great.
But what if this doesn't work.
What if we don't get the objects back.
We need to type else.
And all we're going to do is return.
That means we're going to like we're going to kick out of this function and we're going to not download
any messages because there is no data so there's no need to go forward.
Cool.
So now we have an array of data snapshot.
So if we had 100 messages we would have 100 elements in this data snapshot array.
We're going to cycle through all of them and we're going to need to add them to an array of message
because remember we're going to need to pass one back.
Let's create one at the top.
So go ahead and type var message array and it's going to be equal to an array of type message like.
So what we're going to do is we're going to cycle through every data snapshot.
We're going to pull out the content we're going to pull out the sender ID.
We're going to create an object of message and appended to the array that was a lot of words.
Let's do it step by step.
So for message in feed message snapshot we're going to use a for loop to basically cycle through all
of it.
We're going to first create a constant to hold the content.
OK.
So let content equals message.
And in order to pull out the actual value from the snapshot we need to create a child snapshot.
OK.
So we have a child in our messages and let's look at firebase just so we can remember what this is like
in our message child.
Here we have two objects we have content and Sender ID.
Now the path right here is content that's the name of the key.
So we're going to give it the name of the key but we don't want the key we want the value which is the
string the message.
So go ahead and type dot value.
And in order to get this to work we need to cast it force cast that as a string because what comes down
is a value of any.
And we're going to cast that as a string so that we get it in the right data type.
So that's our content.
That's how you pull the content out of a data snapshot.
Next we need to get the Sender ID so we're going to do the same thing for the sender ID so type let
Sender ID equals message child snapshot for path and the path is Sender ID.
Now the values what we really are interested in.
So call value and of course as you can see its of type string.
So we're going to do the same thing we'll call it a string.
Very very cool.
So now we have both content and Sender ID for every message.
Now we're going to create a message using our message model so type let message equals message.
Capital M and go and put a parentheses there so we can instantiate it.
We can give it some content we can give it a Sender ID and now we have appropriately created a message
using our content and Sender ID from firebase at the end we're going to append this message to the message
Gerais.
So type message or re pen and pass the message.
Very very cool so we're going to cycle through all the messages in the snapshot.
We're going to append it every time and by the end we'll have a nice full array of messages.
Now of course it's saying cannot convert value of type message to argument type message and that's oh
that's because we're trying to append the message to itself.
Sorry.
You just want to pass in this message.
Awesome.
So now once we cycle through we have a nice array full of messages at the end of the for loop.
Go ahead and call the handler and you can see here that we need to pass it an array of messages.
Well we have one message Gerais.
So go ahead and call message Gerais and we're done.
We now can download all of our messages and pass them into an array of type message.
It's seriously so cool and so easy to do.
So now we're going to do is we're going to go back into our view controller right.
Our feet Visi just like here and we're going to go into our feed Visi which as I can see this is not
actually the proper name it's the right name for the file but the class itself is not the right name.
Let's call this feed visi.
And you know what we're gonna have to do that with groups we see as well.
Really glad I caught that I should have done that a long time ago.
OK.
Great.
So now our class is properly declared.
And so what we're going to do first is we're going to set up our table view so that we can actually
download those messages and import them into our table view like we want.
So open up mind that storyboard and open up the assistant editor and you can see here this gray box
is a big bug it's kind of cutting off my interface builder but that's fine.
Go to automatic go to we're in feed Visi here.
So we're going to go to feed visi.
Sometimes it has trouble automatically getting there so we can go there manually Lexow feed visi.
And what we're going to do is we're going to create an IP outlet for our table view so we can call table
view and oh interesting so it's not going to let us let's see what the deal is.
It's of type feed.
That's good.
And I think just changing the name may have caused some problems let's try that again.
Table View.
All right.
So I'm going to actually quit X cone.
I'm going to go back in in just a moment and I'm going to see what the problem is here.
Let's open it back up again and let's go ahead and try our best to connect these two feed VCs here.
We are automatically in feed.
OK that solved our problem.
Now let's go ahead and create an outlet for the table view connect it.
And now we need to set up the proper delegate methods for a table view which you've already done in
this course so it shouldn't be a shock to you but to kind of compartmentalize the code.
I'm actually going to create an extension of you table view and we're going to.
Sorry an extension of feed we see and conform to both of the protocol methods I need to.
That way.
So go ahead and type extension feed VC UI table view.
Can you remember your table view.
Delegate and table view data source like so.
Now inside here there are three that we absolutely need to conform to.
Number of sections in table view.
We're going to return one.
Next is number of items or sorry number of rows in Section.
We're going to return 4 for now just so that it doesn't yell at us or two.
I mean for now and next is cell 4 row index path.
K Those are required.
And now we should be good to go.
Let's get rid of did receive memory warning and let's get rid of that boilerplate code.
So actually in order for this to work as you know with any table view you need to set the datasource
and the delegate in view to load.
So go ahead and type table view.
Delegate equals self and we can do that now that we've properly conformed to these delegates.
We can also call table view data source and set that to be called a self as well so it knows where it's
getting its data from.
So we just wrote a function get all feed messages that returns to us an array of messages.
Now I think that we should create an array of messages here and then as soon as the view appears we're
going to download all the messages.
Set our local array here to be equal to messages array and then we're going to reload the table view.
OK that's just kind of a cool way we can do it.
So let's go ahead and create that array here.
VAR.
Message.
Array.
And it's going to be equal or to an array of message.
And we're going to instantiate it from the get go.
Now let's see.
You know we have set an initial value of 2 here but it makes more sense to set it to be equal to message
count.
Because if we load the app there are zero messages it will show 0 messages.
That's perfect if there are five it'll show 5.
That way it's dynamic.
Now what we need to do is we need to download all the messages and fill up our local array and feed
visi.
We're going to do that.
In view did appear so that it happens before the view actually is finished loading.
So we're going to call super doc view to appear and call animated.
Now we're going to do is we're going to call our data service instance and now we can get all feed messages
and it's going to return to us an array of feed message.
So call this messages array and let's be more specific let's call it returned or returned messages array
and we can set self messages array.
So this one that we just created equals returned messages array.
So now that they're all downloaded our array is the same.
But in order for our table view to show the changes we should set self table view we should set it to
reload its data so that it updates what is displayed on the table view.
Super duper cool.
Now we can properly download all of our messages.
We can update our array and we can reload our table view to show the changes but we have not yet set
up our cells.
OK so let's do that.
Let's go ahead and create a cell and we're going to use dequeue reusable cell with identifier.
You've probably done this before on this course already decoying the cells so that they can be reloaded
at will and just save a ton of memory space in the Table View and then we're going to go ahead and return
the cell to the table view.
So to do this we're actually going to use guard left.
That's because it'll allow us to create a constant of our cell.
If there is a value and if there's not then we can return an empty table to sell it's just a safe way
to do it.
So go ahead and type guard.
Let sell.
Equals.
Table View.
And we're going to d q a reusable cell with identifier.
Now that identifier we have not yet set.
And if we don't our app will crash.
So go ahead and go into the storyboard and as soon as it loads we're going to select our cell.
Then in the attributes inspector we need to set a reuse identifier and we're going to go ahead and type
feed Zelle And you know what I'm actually going to copy that so that I can just paste it straight into
feed Visi our identifier is feed cell.
OK very cool.
And you know what.
In order for this to actually use our feed cell subclass we need to force or we need to optionally cast
it as a feed cell.
Great but what if there is no value.
What if what if it can't do that successfully.
Then we need to go ahead and call.
Else and we need to return a table view cell but we can just return an empty one like so we're going
to return you need to call return first return you table you sell.
And now it's not going to yell at us because it has what it needs.
Next we're going to go ahead and set up an image because if you remember in our feed cell we need an
image an e-mail and a content.
So we're going to go ahead and we'll set that up now.
We're going to call Let image and we're just going to.
For now we're not going to download or upload any images so we'll just use the default profile image
by calling you a image named and the name is default profile image.
OK.
Very cool.
We're going to go ahead and we're going to get the message.
OK so let's say that we have our messages right.
Message equals messages right.
Whoopsies and we want to pull out the message that is at cell once we get the index of 0 because that
gets the first item.
Let's say we want the second message we get the index at 1 and that returns the second message.
So to get all the messages we're going to just call index path dot row and this function kind of works
like a for loop.
It works through the entire message array.
And for all of the items in the array it's going to basically populate them based on the row of the
table view.
Very cool.
So our message has now been instantiated and now we can go ahead and configure our cell.
So since it's a feed cell we can call cell dock configure cell.
We can give it a profile image and you know what since we called it like this and we're calling it with
a string name.
We actually need to unwrap it.
Our e-mail is going to come from message dot sender ID.
OK.
And our content is going to come from message content.
Now when we're done we can return this cell to the table view and it will display after it's downloaded
everything.
Let's go try this out.
Let's see how we did.
We downloaded all of our feed messages.
We reloaded our table view.
We set up ourselves to go through the downloaded data and set each cell to have individual unique data.
Let's go let's go try it out and see how we did.
Let's see if it did what we asked.
I hope it did and let's just give it a shot.
Let's see.
We should have two messages from firebase.
Hey look at that.
Awesome.
Let's look at firebase we had.
Hey what's up.
And then this one I accidentally sent earlier and it did not have any content so we're going to need
to fix that later on.
But for now look it's downloading everything.
That is the message and that is the second message that's perfect.
Very very cool.
So yeah it's working.
The only issue is that we're getting the identifier the unique ID which you probably don't want to be
public.
Instead of getting the e-mail and we're going to set up a function in a later video that's going to
convert the sender ID into the email from the user's account.
Awesome job guys were downloading messages into the feed.
And you know what let's try posting one let's see how it works when we post one.
Hey hey hey.
Post and we get our new post right there that is so cool.
Amazing amazing job.
In the next video we're going to set up a function that's going to turn these ideas into e-mails and
we're also going to set it so that all of this content shows up at the very top of our feed the latest
content.
I mean at the very tippy top so amazing work let's head over to the next video and I'll see you there.