Swift: Firebase 3 - How to Group Messages Per User (Ep 10)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what is up guys welcome back to the channel on a very nice Monday morning hope you guys have had a good weekend for those of you that are having a slow Monday why don't we kick it off with episode 10 of our firebase 3 real-time chat app video lesson now our app is becoming a super interesting because it's really coming together to form a nice chat application with a lot of its core functionalities in place so when we go over what we did in the last episode and then we'll talk about what we will do today so in this simulator we have a logged in our John Snow user and inside of the table view controller we have a list of messages that are being populated from this messages a node with these bits of information such as from ID text timestamp and to ID so this to ID is what is being printed on the top text label and the to ID of any be refers to this brand start character so all this information is being entered within chat log controller inside of the method called handles send and we're just pumping in all this data into our messages node like so so all of that is what we kind of worked on in the last episode of episode 9 and make sure to watch that in the link found in the description below and get kind of caught up before we start today anyhow let's begin with what we want to build out for today's video tutorial and take a look at my completed application we see that not only do we have the name for the user inside of the message we also have the user's profile image view on the left side as well so we're going to go ahead and implement the functionality that brings in those two components and along the way I'm going to show you some nice tips and tricks as to how to reuse your components that you've already written and to also perform some really nice cool tricks with code so before I get started I want to fix one problem that I've seen in the code and essentially inside of login controllers handlers inside a registered user into databases with UID we have this hard-coded database URL that you guys don't have access to in terms of the firebase console so I'm going to just remove it and remove this from URL as well so having it done both of that have those two steps we now reference whatever it is inside of this Google service P list instead so you guys will have a better way to access your database if you just use reference like that so moving on to getting the name for our user like have at this top row should really say branch dark instead of this long to ID so when we go ahead and go into messages controller cell for row at index path and inside of this bit of code right there instead of studying these two IDs I will first unwrap it by saying if let to ID equals message to ID and I'm gonna try to actually let's see not equal whether I'm going to get the user right here users and then get this user via this reference right here so let reference equals fi hard database the database reference and child will be the message or not messages but users node and then we'll specify a second child which gets us to the to ID getting us to this node right here so having that reference set right there I can observe a single event type value and I'll enter right there with a snapshot and I'll print out this snapshot value like so and I'm going to run the application removing that comma didn't line out so I'm printing out those snapshots just to show you guys what is going on and make sure you guys understand what the snapshot value is so snapshot is being printed out down there so it's just a printing of snapshot with email name and profile image URL so to access this dictionary here I will access snapshot value like this if let dictionary equals snapshot not value cast it down as a string to any object dictionary like that and here we will simply set cell message Z cell dot text label dot text equals this dictionaries the name object like so and before this will compile we need to cast it as a string from any object to string like that and we run this application now each one of these rows will actually print out the name of the message recipient instead so Brad stark bran stark Melisandre and so on so forth so that's how we would give the name and now we want to actually get the image on the left of the name as well so let's see how do we want to do this we don't really want to repeat any type of work for example I don't want to construct this cell so that I can add an image view in there again so what I'm going to do is we use this component inside of new message controller we use this entire cell right here and this comes with this profile image view so I'm just going to copy that out a new message controller so below if I drag this console down a little bit we have this class called user cell so I'm going to actually create a new group up here and let's follow some MVC conventions by putting this entire user cell which is really a view inside of this file which I'll create called a user cell just like that and then this little important do I get followed by the pasting of the entire user cell in here so let's remove those two spaces and build so run I think it's going to look exactly the same as before now my file is nicely tucked inside of or the users is technical side of this file here so moving on let's now try to register this user cell inside of my messages controller right above inside of viewdidload I'm going to type in view or a table view register class so this is how you register user cell self gets the class and what is this reuse identifier well I'm going to create the cell ID up here let's--oh ID equals cell ID now I can actually remove this hack right here so that's the hack because we actually need to DQ ourselves from the teeth table view instead so table view DQ with this cell ID guy and index path from this parameter right there and if I run this application now you'll notice that these cells are going to start looking a little differently inside of messages controller in other words we have some spacing on the left which is actually the spacing on the Left right there for the image view now I notice that the spacing is a little off here what I mean is it's really tight so I'm going to actually copy over this 72 height for the C for the table view and just paste it into my message controller table you I run the application now my height is going to be 72 instead of I think it's 44 the default height so here we go looks a little better and I think I can remove this snapshot print statement as well this console is getting a little gnarly right now anyhow right now once you fetch the image for the profile image view inside of this cell now in other words I can get it like this so inside of this dictionary for this snapshot value I have access to profile image URL which is going to be unwrapped like this let profile image URL equals dictionary and here we'll use the kea profile image URL and we'll brace it off like that and now we can access cell that profile name interview or we should be able to do that but we can't access this because this cell right here needs to be casted down to a user zone and now I can access this profile image of you inside of my user cell class right there let's go back to the previous file here I'm going to call load image using cache of string profile image URL so this needs to be cast it down to a optional string here we go so writing this code now our image will show up on the left side of the message right there so that's how we would achieve this effect all right pretty good stuff hopefully nothing too confusing yet and we're going to move on from this to actually organize our code a little bit better now you see all of this code right here starting from this to that this really doesn't belong inside a cell for row at index path it actually belongs inside of users cell and the reason is because self a road its main job is to just return a cell doing all this setup work to show the text and the image really should go inside of the view itself so I'm like perhaps show you guys how to clean up your code so that it's easier to manage now because I have message right here I can actually create a proper user cell called message and I'll create this property as optional inside it's set so you did capital as et we will actually execute all of this code right here inside of the cell instead let cut all of that and then I will go into user cell and paste all that code in here okay now I will need to resolve some of these errors by first importing firebase gift.that in their message we'll need an optional like that and what else is wrong here so no longer needs cell because text label is inside of the cell so let's remove this as well and I think this needs a self right there and this also needs a self finally remove this guy down here and I believe this needs an optional so this is the logic that is performed every time we set message going back to messages controller all we need to do is set cell dot message I'm just build so we get this Auto completion there that's that message from the line above also I will remove this comment here that we don't need anymore and running this now we will get the exact same layout of our cell with the name and profile image view just like that everything looks good so now I can just simply work from within my cell instead of the very very bloated controller file cool so this is just a technique to organize your code a little better hope you'll hopefully you guys kind of understand what's going on there now the next bit of implementation that I want to show you guys is how you would actually a group or cells together based on the user and a typical chat application you only have one row per user and that row shows the latest message for that that message for that user and the latest message is based usually on the timestamp and it shows the last message sent so this timestamp value is what we are going to use to kind of group these cells together so that they kind of look like this instead now to make this easier to follow I will first let this time label on the right side and then show the timestamp for the message itself let's go to users cell and I'm going to create a time label right below profile image view right here so let time label be a type UI label so this is a closure block which we will specify a label and return this label from this closure and executing this closure with these two parentheses right there so label I'm going to set some dummy text which will just say our minutes and seconds like that so I am going to add it into this cells subu hierarchy by adding sub view time label like so and to put it inside of this cell we need to actually use some iOS 9 constraints so before I can do that let's set this property to false now we'll just added these constraints right here okay so what is the actual constraint we need first well we need X Y and with anchors so down here I will first let slide you right anchor to be pinned on the right side of these cells right anchor by specifying time label dot right anchor constraint to the self dot right anchor of the insiders cell and the time labels Y anchor will be a center Y so such a why anchor is pinned to the center of this text label like this so text label dot Center Y angered and then time label dot with anchor so with anchor that constrained so you constrain to constant of perhaps a value of 100 and the finally the height anchor will just be constrained to the text labels height anchor like that now let's just steal these active values so I don't we and put it down here so writing this I should be able to see a time label has this bit of text on the right side of my myself so seeing as how this is kind of being printed out above right there instead of using the center of why I'm going to just pin the the top anchor like this a top anchor this pin - so you constrain to self dot top anchor with a constant value of perhaps 20 pixels not acted equals sure so this is going to put the time label 20 pixels from the top of the entire cell there we go that's what it looks like I feel like that's a little farther down that I would want it to be so I'm just going to bring that down or bring that up by perhaps 2 pixels so I'll run that and I want to actually shrink this bit of text down a little bit by bringing the font to a UI font and the font system font of size 12 and for clarity's sake i will change the text color to a UI color of light gray color I'm going to run this now and you can see that the obvious change inside of the the time label there goes wait for the suit start and now it is this bit of text right here hopefully yeah you can see that perhaps I'll use a dark I think light gray color site and then let's just bump this up to 13 perhaps so with all of that in place I can actually bring in the the actual time stamp down here if I go to user cell user cell message I can quickly set the text label like this whatever we set this message we can just simply say time label dot text equals message dot timestamp right the time stamp isn't it is never so we need the string value out of it via that method right there okay so printing out the time stabbed in there now I think it's actually a little too light so let's bring in dark gray color instead make it a little more visible this time stamp is actually an integer integer representing the number of seconds from 1970s so that's how that works in order to print the date out properly I first need to convert this timestamp to an actual date and that's very easy if we just set a timestamp so the timestamp date equals and it's date like this and we'll use this constructor of time interval since 1970 of message dot timestamp so time stamp dot double the double value and that's what it needs to be so none of this really compiles that well so instead of unwrapping it like this and like this let's do it a little safer by saying if let seconds equals message dot timestamp dot double value like so we can actually set this right here see let me just paste that in there equals NS date time interval since 1970 with this seconds value right there so cool cool stuff and just paste that in here as well and let's see I can actually use time the timestamp date dot description in here instead now and with this value we're actually just going to print out the raw string for the date giving me this really really long string right here so typically a chat application just prints out the hour minutes and seconds or basically the hour and seconds but in this case I will use a date formatter so date formatter equals NS date formatter and here we specify date format of format date format equals this value right here so H H mmm s and then perhaps I need to asses right there if all you have a so this is kind of cryptic and you pretty much have to Google the date format strings for an estate to figure out what this does now we can get the date formatter string from date time stamp date and here we go let's see what the timestamp actually looks like whatever we use this date formatter instead so now it says 11 26 45 with a.m. and that is being printed basically based on this code inside of this date format string so just google that and you'll find out what that means in a perk perhaps better explanation on google cool now let's see how we should group these messages kind of together in a single row so we actually want the last message for brand start to be this single message room essentially we want this last message sent at 11:51 after all of these messages above so how do we do that what is the easiest way of constructing a data structure that allows us to group these messages together well if we go to messages controller now all these messages are being upended onto this messages array inside of line 14 right so why don't I also include a messages dictionary and will instantiate a string to message dictionary like this and now we have this dictionary here so what do I want to do with it is the question and instead of just appending here I'm going to set the value of self messages dictionary and we'll use the value of to ID inside of this so we're just going to use message dot to ID like that equals message okay so Brown starts to ID will just be the value of message but we can't really do this yet because we need to safely unwrap d2i d so message to ID and then we will just set this guy in here and use to ID like that so this might be a little confusing to some of you guys out there so why don't we just put a breakpoint in here and see what this dictionary will contain every time we receive a message inside of this observation here so we get this breakpoint here message dictionary is this right here has 0 values and we hit 1 continue and inside of here now we get the first message which is this bread start Bratt start a brand start character and then we keep hitting this continue button and then we get more and more dictionary values so as soon as we get a different recipients ID of our dictionary and so our app still looks the same but now we have this dictionary here that contains all of the messages but only one per recipient or per user and we'll use this to actually fill out our table view instead so that is how you would kind of use a dictionary or a hash to fill out your table use I'm going to show you guys how to do that exactly so every time we put a message inside of this dictionary the value kind of changes and if we set let's see if we comment down self messages this entire table view will now show nothing because we now have messages that count of 0 the messages are no longer being a pendant into that array and I'm going to say this is that self messages equals self dot messages Dictionary dot values right so basically all the messages inside of the dictionary will be this array now but we can't do this yet and this is a swift issue we just have to cast it using this array right here and doing that we can actually reconstruct this array every time we put something inside of the dictionary and having this done we can load the table view now where as let's see in line 51 we load the entire table you with reloading and inside of here we get the actual message of the brand start character and it just so happens that this message is the last message it's not always the case that the last message is the right one so well perhaps look at why that is and first I want to actually show you something else that is occurring here so you notice how these messages are not being sorted properly basically I want this ingred message to be the first one on top so these two are correct but this Tyrian message should appear above this melisandre one because the time is 17 minutes after 11:30 3 so the way you would do that is to actually sort this entire array and every time we could reconstruct this messages array on line 46 we can sort it right below with sort in place just like that and we hit enter here and here is how we sort two messages with M 1 and M 2 to be more explicit let's call it message 1 and message 2 and we simply return the sort or of message 1 dot timestamp dot int value is greater than message to timestamp type int value so I know some of you guys I've never seen this before probably but this is how you a sort for and if sending order or descending order rather so we have the messages now in a descending time order so this is the time that is greatest and this is the time that is the least and now our messages are being placed properly inside of our table all right that's going to wrap it up for today hopefully you guys saw some of the useful tips and tricks to reorganizing your code so that it's easier to manage later down the road also how to group your cells together so that only one message shows per user using a message dictionary or a hash it's a very useful way of doing that I know some of you guys might be a little confused on how that works but walk through the debugger and look at how the message dictionary and the messages array is constructed as we observe everything inside of our messages inside of firebase okay and also make sure to like today's video if you enjoyed the content make sure to subscribe as well doesn't really help me out it helps the channel out as well alright in the next episode let's figure out how we can put all of the users messages inside the entire chat log controller really exciting steps I hope you guys look forward to that and furthermore if you want to download the project for today's video lesson you can click on the download link above follow me on Twitter ad build that app finally if you want to learn more about iOS development click on the three playlist links on the bottom to get even better at iOS programming that's about it guys keep on coding and I'll see you next time you
Info
Channel: Lets Build That App
Views: 38,527
Rating: undefined out of 5
Keywords: ios, swift, development, tutorial, learn, xcode, programming, code
Id: fyqksNlC8ks
Channel Id: undefined
Length: 28min 13sec (1693 seconds)
Published: Mon Jul 11 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.