Diffable Data Source (Swift 5, Xcode 12, TableView) - iOS 2020

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what is going on everyone welcome back to another swift video in today's video we're going to be talking about ui table view difficult data source so this has been something that a lot of you have been requesting it's fairly modern and kind of newish so i figured it's time we finally go over it so what is a difficult data source it's basically a way for you to supply an object to either a table view and this is also applicable to collection views and where the data source can automatically diff the models and the data that you want to present and it can animate and update your data and your ui for you so here's a developer documentation page for it i'll link this down below we're not going to read it we're going to write some code and be cool about it and here is an example of what we're going to build we've got a table view here and i've got an obnoxiously large action sheet and we select one of these we actually don't call reload data but we've got a difficult data source going on behind the scenes here and it actually automatically is able to create this concept of a snapshot and apply the changes and update the ui with a pretty slick animation so all that said make sure you absolutely destroyed that like button as per usual helps out video engagement if you've been following along hit subscribe while you're at it for daily uploads keeps channel going and growing get xc ready get excited let's get into some difficult data source all right we're going to get started by opening up xcode and creating a new project we'll stick with the app template and let's go ahead and call this diffable data source make sure your language is swift interface is storyboard and lifecycle ui kit go ahead and continue we'll save it to our desktop and first things first i'll expand this xcode window to give ourselves a little more room to work with and we're going to be working primarily in the view controller here so let's come in here bump up the font size let's also pick a simulator while we're at it hit that run button and you should be greeted with an empty app just like this so differable data sources so the idea behind a difficult data source as i mentioned in the beginning is a object that can diff the models that you are supplying to a table view and update it automatically via this thing called a snapshot so all of it will be done through code we're going to create our models but before we do that we're going to want to create a plus button in the top right of our screen and every time we select it we'll show a sheet from which we can select an item to insert into our table view so let's go ahead and just jump into the main.storyboard for a quick second select your controller and just embed it in a navigation controller via the editor option up here embed in navigation controller and that's the extent we'll be in there and let's jump back to our view controller so before we actually look at the difficult data source we need to create a table view to apply that data source to so let's just come in here and with an anonymous closure pattern let's create a table view like so so we're going to create it we're going to return it and we're going to make sure we register a cell to it which is going to be a tableviewcell.self for the identifier of cell we are also going to say the delegate is self make sure you don't assign the data source there just the delegates since the data source will be another object the next thing we're going to want is the actual declaration of the data source so we're going to say var data source and this is actually going to be just the type here so this is going to be a ui table view data source and if you notice if you try to create it like this you're going to get an error or if you don't get an error when you try to implement it you'll get an error and the reason is is because this type is generic and it expects the type of a section and each model in that section in these brackets so let's go ahead and create those models and we'll talk through them a little bit about how we created them so first we're going to create sections with an enum and i'm just going to add one section in here and we're going to create a model called fruit it'll be hashable and have a title in it and in the data source we're going to say each section will be a section and each section will have a fruit in it just like that let's see cannot specify non-generic type let's see why it's complaining this is supposed to be ui table view difficult data source not just a normal data source and now you'll see everything will look correct and actually if you get rid of these now you might actually see the error that i was talking about just a moment ago just like that so let's talk about these models so the idea with a difficult data source is we need to provide models that the data source can internally diff in other words figure out differences for and based on a difference it can animate and update your table view automatically so to create a diff your models need to be hashable in other words they need to have a hash associated with it so the table view under the hood can compute the differences generally sections are best represented as enums because enums are hashable by defaults and models are best represented by a struct marked with a hashable to conform to that protocol so let's stick with this and move forward now that we've declared it up there let's go ahead and actually create it here but before we do that we want to make sure we don't forget to add the table view as a sub view and that we don't forget to give this guy a frame and let's assign that data source so this is going to be a ui table view difficult data source uh and open up that constructor here and you'll see there's only one initializer first parameter is a table view to apply it to and the next thing is a cell provider which is a closure that takes the table view an index path and the actual model that you supplied in the generic declaration right up here and if you look at it it looks awfully familiar this looks a lot like the function cell ferro index path and in fact it actually functions exactly the same so here we're going to say table view we're going to dequeue a reusable cell with the given identifier assuming i can spell it correctly just like that the id is cell that we registered and for index path and that index path is coming from the closure parameters and what's also unique about this closure is that it passes in the model for the given position based on what we specified as the type so here we're going to say cell text label and all i'm going to do here is assign the text to be model dot title and title is this thing right here in our fruit so fairly straightforward so let's go ahead and hit command r let's let's make sure we're building and we should see our app running here with an empty table view hopefully cool looking good so we can see there's a table by the cell separators are a little subtle but they're definitely there so let's go ahead and start looking at what snapshots are let's add a plus button up here and let's start adding in some rows so adding a plus button is fairly simple let me just give this a title of let's call it my fruits and let's add that plus button which is a right bar button item so it's going to be a ui bar button item with an image and a style the image is going to be a system image of plus style we can stick with done target self and the action here i'm going to go ahead and say did tap add we're going to create this function annotated objective c since it's a selector and let's leave this empty for just a moment we're going to need an array that's going to hold fruits and that's what we're going to use to tell the data source to update itself so let me call this fruits and this is going to be a array of fruit models and when we tap on that plus button what we want to do is we want to show an action sheet and it's going to be a alert controller with a title of select fruit message of nil and the style is going to be an action sheet here preferred style will be an action sheet just like that and then we're going to present the action sheet now of course in your actual app you wouldn't use an action sheet you would use your actual data but just for the sake of this example here what we're going to go ahead and do is we're going to add a cancel action first so this is going to be a ui alert action with a title of cancel cancel and nil and i'm going to create a for loop here so we're going to say for x in zero to let's do a hundred and every time we're gonna add in a new uh action and instead of it being cancelled it's going to be fruit x plus one style will be default and the handler instead of it being nil we can actually do something in here make sure you do weak self so you don't create a retain cycle and what we're basically going to do in here is we are going to first create a fruit and this will be fruit with a name sorry with a title which will be fruit x plus one we are going to append it to the models array which is called fruits just like that and then we're going to tell the data source to update so i'm going to say update data source and we haven't created this function yet so no need to panic so let's create this function and this is where we need to create a snapshot and apply it to the table and the snapshot is what the table view rather the data source can use to update the table of view automatically so here i'm going to say a snapshot is a ui rather instead of uins differable data source snapshot and this is again generic so we're going to say takes a section and a fruit type and on the snapshot we want to append a section and the items so sections is fairly simple we only have one and the next thing we want to append is the item items plural and that's going to be our fruits which is an array of those fruit models and then we can say on the data source we can apply a snapshot and do we want to animate the differences yes because we're cool are we going to add a completion no because we're lazy so before we review this code let's go ahead and just hit command r and see this in action more importantly let's see if i broke anything so we have a plus button we've got a title if we hit this we should see a super long list pop up here so let's go with fruit one all right there's fruit one animated in pretty cool fruit two fruit three so on and so forth i can sit and go through this whole list so i'm going to call out two really important things here the first thing is that the model needs to be hashable and that hash is how it's going to figure out if the data needs to change now there's an implicit thing that everyone gets confused on in here and that is you need to make sure that every single model is truly unique so for example we have fruit 1 2 3 and 21 in here watch what happens when i hit fruit 1 again all right what happened there well clearly the app crashed but if we come into here let's take a look at what actually caused this to crash so this is saying terminating app due to uncut exception ns internal inconsistency exception fatal supplied item identifiers are not unique so it's it's fairly straightforward but let's let's define this in english so what this is saying is the table view data source tried to create a diff of adding that new snapshot rather applying the new snapshot that we're giving it down here and what it's saying is it found a model with the same identifier same hash as something it already has so it's not able to compute if there's a difference now why is it doing that it's doing that because we're creating a hash based on just a title in a fruit so if we try to add the same types of fruit multiple times it's going to basically crash because it doesn't know if there's a difference generally models are a little more intricate than one item but the solution to this is basically implementing your own version of hashable which is this hash into hasher function and supplying unique values so that's a really important distinction to call out of if you ever see crashes like that that's actually what's going on what you'll also wonder be wondering rather is how do you deal with selecting a cell with this different type of data source so the good news is uh it's fairly simple and the even better news is it's actually identical to what you used to do before so if we do did select row at index path the first i'm going to do is deselect it and you can actually get the item from the data source so we can say let fruit is data source and let's see item identifier so you can get the item identifier from the index path here and notice it returns a fruit optional so here you can just pass in the index path and instead of actually taking the index path in this function here and checking in the array of you know what was selected which can be error prone sometimes this is far simpler and more so than being simpler this is more uh crash prone rather crash resistant so you're not gonna you're not gonna run into weird exceptions where index indexes are out of range or out of bounds but let's just go ahead and print out fruit.title and let's just see this in action in other words now the data source is also responsible for pulling out the model for you even though you're using the same function here did select road index path it makes your life slightly simpler we can disregard these uh constraint warnings in the console because it's complaining about my obnoxiously large action sheet here so we've got a few things in here and clear this out with a command k and if we select it you'll notice we get the respective selection that printed out just like that and there you have it that's how you can use a difficult data source you can use it for both table views and collection views it does simplify your code no more data source number of rows number of sections and the most the most the best thing about this the most wonderful thing is if you're ever used to getting data and then doing something like table view dot reload data you're not going to have to do this at all anymore the beauty is just update the snapshot apply to the data source and the data source will do the reload for you and it'll also do with an animation with a simple boolean value of true here so that's basically all i've got for you guys today so let me know down below do you guys use difficult data source if you have an older project you plan on migrating i think it's pretty subjective if it's worth it or not uh of what benefits it brings to you i'm not sure if i mentioned it but i'll call it out again but this is only supported in ios 13 and up which is most uh apps support minimum so be cognizant of that in case your app does support older versions hit that like button if you haven't done so already helps out with video engagement quite a bit comment other feedback video suggestions down below hit subscribe while you're at it for daily swift uploads thank you so much for watching i'll catch you guys in the next video you
Info
Channel: iOS Academy
Views: 4,906
Rating: undefined out of 5
Keywords: swift 5 tutorial, swift 2020, swift, swift 5, swift tutorial, swift for beginners, swiftUI 2020, swift programming, swift basics, swift apps, make iPhone app, swift make first app, swift table view, table view diffable data source, data source table view, diffable data source, collection data source, diffable data source swift 5, tableview custom data source, diffable data source table view, data source diffable swift 5, swift 5 diffable data source, table view swift 5, iOS
Id: Q2SmtfaxuW8
Channel Id: undefined
Length: 16min 54sec (1014 seconds)
Published: Tue Dec 01 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.