CloudKit CRUD Functions in SwiftUI project | Advanced Learning #22

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] all right welcome back everyone i'm nick and this is swiffle thinking uh in the last video we connected our app to cloud kit so our app is already connected if you're just joining you need to connect your haptic cloud kit in order to do the code in this video if you don't know how to do that just check out the last video in this playlist so in this video we're going to now do some crud functions in our cloud kit container that is creating reading updating and deleting items in our cloud kit database yo yo yo welcome back what is up everyone uh in this video we're gonna do some basic crud functions that's create read update delete in a cloud kit database in order to do that you need your app to be connected to cloud kit so in the last video in this series we already connected our app to cloud kit so if you are just joining and you're not yet connected you're not going to actually be able to use cloud kit until you do all that setup so i would definitely recommend watching that last video before this one but if you are set up you should be ready to go so i'm going to go to our cloud kid boot camps folder here i'm going to right click the navigator create a new file and let's create a swift ui view and we will call this uh cloud kit let's call it cloud kit crud boot camp let's click create and we are not going to use a simulator a second so let's just come in here let's open up a canvas so we can see what we're doing quickly in swift ui we have to build out a relatively quick small ui for this video alright so i'm going to create let's create a scroll view open the brackets inside the scroll view let's create a v stack open the brackets at the top of the v stack let's add a text that just says cloud kit crud and maybe we'll press the control command space bar to open up the emojis because everyone loves a good emoji let's throw in maybe some clouds because we're in the cloud kit of course i'll make that a font headline let's make it maybe underlined and let's move that out of our view here so we're going to make a extension of cloud kit crud boot camp let's do a private var let's call it header of type some view i'm just going to paste that inside and we'll put our header at the top of the screen below that let's add in a text field open the parentheses and i'm in ios 15 so we have some of these new completions here with this prompt but my project is actually building for ios 14 so i can't actually use this prompt yet so i'm going to delete that and the text field placeholder let's say add something here dot dot and then we need a binding string of course so let's create our view model let's create a class cloud let's call it cloud kit crud boot camp view model uh let's conform to observable object let's initialize it in our view here with an at state object private var vm equals cloud kit crud boot camp view model and in here let's put our at published var let's just call it text of type string set it equal to a blank string to start and let's bind to this text down here and use the money sign vm dot text let's click resume we should have uh our text field on the screen here all right let's give it maybe some let's give it a frame with a height of 55. let's give it a background color of let's do color.gray maybe that opacity of 0.4 just make it like an off gray and let's give it a corner radius of 10 and then on the v stack let's just add some padding so we pop it in there before the background let's actually add some padding of leading as well just to get the text to come off the edge a little bit looks a little better let's make that a sub component so down here private var text field of type sum view paste that in let's put the text field on the screen and one more we need a button so let's add a button quickly and open the parentheses open the parentheses and let's use the action and label all right the action of course we don't have yet but the label we can add let's add a text that says add let's give it a frame with a height of 55 as well let's give it a frame with a max width of infinity let's give it a background of color dot maybe pink and we'll give it a corner radius of 10 as well and let's give it a font of headline foreground color of white let's click resume see what it looks like cool cool cool let's take our button and make it a sub component let's create a private var let's say add button of type some view open brackets let's paste in our button i'm going to put the add button on the screen here moving faster because we've done this many times in my courses as you already know and i just realized that we're going to want a list down here so we can't use a list inside a scroll view so let's change this up a little bit let's change the scroll view to a navigation view on the v stack let's call navigation bar hidden true so we don't actually see that top area and then underneath the add button let's add a list open brackets and for now let's just put text saying hi just to make sure we get the list on the screen and of course let's list style let's give it a plain list style cool we are going to update this list in a second but for right now let's just start adding some items to our cloudkit database so basically when i open the app and i start typing and i click add i want to send that to cloudkit so firstly we want a func that's called save button that's called add button pressed open close parenthesis open brackets when we click this let's first make sure that the text is not a blank string so we'll say guard text dot is empty let's make sure it's not empty with the exclamation point here we'll say else return so it's empty we just won't do anything and let's create another private func saying add called add item open close parentheses open brackets and when we call add item we want to pass in with a name of type string so in add button press let's call add item and let's pass in whatever is currently in the text i'll just note here that uh you also might want to check before you do anything in cloud kit that the user is connected to cloud kit so in the last video we did a um is signed into icloud we got their icloud status we should definitely be doing that before we were actually doing anything in icloud uh but we already connected to icloud again in the last video so we don't have to really worry about that in our simulator right now all right and when we call add item we want to create an item to actually add to the database then we want to save it to the database so we're going to need another function called save item open close parentheses open brackets and in order to save an item we call ck we need to first import our cloud kit framework and we're going to need to call ck container.default and i'm going to type in database and we have an option of where we want to save this data in the public database a shared database or a private database and i started talking about this in the last video again the your general info that will be shared between your users so all different accounts can access that data would go into your public cloud database if it is private to your current user or the people that your current user have shared it with we can put that in a private database and that's not going to be accessible by all of your users uh but for right now let's just use the public cloud database because it's a bit simpler and probably more common so we'll call public cloud database dot save and you can see here we need to either save a subscription a zone or a record and we're going to do a record and of course we don't have a record so when we call save item we should actually pass in a record that's of type ck record we can pass in our record to our save function and then we can press enter on our completion handler here and this will be a returned record so if it successfully saves it'll give us back a returned record and a returned error for right now let's just print those out so we'll say record colon let's print out the returned record and let's also print error colon and we'll print out the returned error all right so we need to call save item from our add item but of course we don't have a ck record yet so we need to create a ck record so in here let's say let and we are actually going to be uploading fruits in this video so we'll say let new fruit then we'll set it equal to a ck or record open the parentheses and then we need a record type and now we need a record type of course so i'm going to go back to our cloud kit container which i still have open from the last video so in our cloud kit container you noticed last time that the record type we have is users and this is basically all of the data types that we have in our database here so all i have is users and we don't have fruits or anything like that but fortunately the cloudicook container is smart so if we upload data that has a new record type so a new name for a record type it'll actually understand that it is a new type so we don't even need to tell our database beforehand what we are going to upload instead we can just upload a new type and it will accept it so we come back here and the type and the type we're going to have is fruits just that simple i'm going to call it fruits and then we can call save item and we can pass in the new fruit which is our record now when we create this ck record it's just going to create a plain piece of data in the database it's not going to have any data other than the fact that the record type is fruits so we need to add to this record all of the data that we want so i'm going to call new fruit and then this record works just like a dictionary so inside the fruit i can access a key and the key i'm going to make right now called name and we'll set it equal to the name that we're passing in to this add item so we can actually add whatever keys we want here and then give them values so if this was a existing record and we added this line of code it would just overwrite whatever is currently in the name but right now there's obviously nothing in this fruit so we can just add a new field called name and we're going to give it the name that we pass in here i'm going to right click on ck record and jump to definition quickly just because i want to show you guys that i wanted to show you guys in the documentation uh these are all of the types that we can send it directly into our cloudkit database so name is obviously a string so we can just send that directly we can also send dates and data booleans integers a whole bunch of really cool stuff one thing i do want to point out though is that in here you don't see images you don't see videos you don't see audio and that's because we can't send an image directly to cloudkit instead when we're sending those data types we need to first convert them into ck assets and then we can load a ck asset to the database all right going back to our code now this should be working so let's call add button pressed from our view so coming down here we have our button let's call vm dot add button pressed and i'm gonna build and run this to a simulator because my simulator is actually connected to cloud kit already so i'm going to hide this canvas here and let's actually make our cloud kit crud bootcamp the first view in our app so i'm going to go to the app.swift file where we have our app main call and i'm going to change from cloud kit to user bootcamp let's use the cloud crud bootcamp i want to reiterate one more time that if your simulator device is not connected to icloud or cloud kit it's not going to work so you first need to connect then you can go ahead and use cloud kit so we're connected and if we press add right now with nothing nothing should actually happen but let's type in maybe apple press add and we gotta print out here so it looks like a record was actually created we can see it it's got a name field called apple and we can see the creator record id that's my my personal record id so it knows who created it and we got some other data here that i'll go over in a second we have error as nil which is great and i just noticed that after we add the apple obviously the text is still here so after we get this call back here in our save function we actually want to reset that text field so we'll say self and we should be a weak reference self.text and we'll set it equal to a blank string i'm going to run the app one more time and this time let's start typing in let's add a orange let's add a watermelon and maybe and maybe a coconut who doesn't love a good coconut right all right and i got a quick error because we are on a background thread so this should actually be a dispatch queue.main.async and then we can do this in here but we now added four items to the database so let's just check them out so i'm gonna open back up uh my my icloud container i'm gonna reload it and you'll see here just like magic in our record type we now have fruits let's click on it and let's try to query it we're going to get that error message that we got before record name is not marked queryable we saw this in the last video we have to go to our indexes we now have our fruits record type and by default it's giving us the ability to query search and sort on name not on the record field and let's just add a basic index for the record name so the record name and let's make it queryable save changes and now we should be able to query on the fruits so let's go back to our records select fruits let's query and awesome so we can see here all of the fruits in our database and we can see the names right here orange watermelon coconut and if i go in and click on one of these we get some other data as well we can see that this is in the public database we can see the when it was created and when it was modified and even cooler than that we can see who less who created it and who last modified it so this id here this underscore 53b2c that is actually my current user icloud id so in the last video we went and we queried on users and you can see that when i query on users the one user that we have which is my current icloud account has the same name that we can see here so by default icloud gives us some of this metadata on who's creating this who is updating it and that's really really helpful to us as developers because otherwise we would have to create all of these fields manually something else that's also really cool i'm going to go back to our fruits because that's where we're working right now something else that's also really cool is that this cloud kit console is essentially like a mini cms because we can come in here we can come in here and we can add records manually i can create a new record here i'll make it type fruits and i'll give it a name see it understands already automatically that if we're creating a fruit there's a field called name for fruits so this is not here by default but it's here because all the other fruits have a name field so i can add a new one here and let's say peach and click save and just like that i can add it to the database i think we need to re-query and now we have our peach here and we can also go in and click one of these i'll click on watermelon and we can either update data in our database so i can add in i can change the name if we had other fields we could change that data as well now obviously you don't want to get in the habit of updating these manually unless this is something like specific for your team and your admins to update you don't want to go in and be changing all the data that your users are creating but this is really helpful that we can do this we can also just delete items straight from here which deletes them permanently i can re-query and if we click on it one other thing that's really handy is that while we're clicked on it we can click reload we're not doing anything on this right now but if we were running things in the app and it was changing data we can just quickly reload that one piece of content and we can check if it updates so really really cool stuff i'm going to go back to our xcode projects we've got a lot more to do in this video i'm going to just rebuild the app to get rid of this error message here all right and when we're running our app now of course we're adding items but we're not actually fetching items so this hi we want this to be a list of all the fruits in our database all right so i'm going to close out of this quickly and let's create a function let's call it fetch items open close parenthesis open brackets and in order to fetch items we need to call ck container dot default dot and we need to decide what database that we want to fetch from so of course we're saving our items in the public cloud database so we want to fetch right now from the public cloud database in order to fetch we actually need to add an operation to the database so a little counterintuitive that we are adding something in order to get something back but we are adding a ck database operation so of course we're going to need some sort of ck database operation so i'm going to make that its own function let's say funk add operation open close parenthesis open brackets and let's pass that in here and we're going to pass in an operation of type ck database operation let's pass in the operation and now in our fetch items of course we want to call add operation now we need a ck database operation so up here let's say let query equals and we're actually going to create a ck query operation we'll open the parentheses and we're going to pass in a query i'm going to right click and jump to the definition of ck query operation and i wanted to show you guys that ck query operation conforms to ck database operation protocol so we learn protocols in this series hope you guys are now familiar with them but because it conforms to this we can create a query operation and then pass it in as a ck database operation so we're going to end up passing in our query operation directly into our add operation function now of course in order to call this we need a ck query so let's actually rename this to a query operation and let's create a query we'll say let query equals ck query open the parenthesis and we need a record type and a predicate so we take this query and pass it in here and now of course we need a record types so what record type do we want to query on well we just made our fruits so let's query on the fruits of course and then we need a predicate so let's say let predicate set it equal to ns predicate open the parentheses and we're going to use and we're going to give it a value of true if i hold the option button and click on ns predicate we can see that it is logical conditions used to constrain a search uh sort of like a filter basically and here we want all of the items where record type fruits is true so we're going to pass in the predicate here and we should now be able to actually fetch these items now one thing you're going to notice here that is a little strange is that this add operation does not have any sort of completion right so normally when we call these functions they have this handy-dandy completion and we get back some data when we call this add operation there is no completion and i'm not really sure why this works that way but basically we need to add in our completion to the query operation before we add the operation to the database so in here let's call query operation dot and i believe it's called query result block so i'm going to hold the option button and click on it and we can see that the query result block is of type operation result which is a result that has a cursor and an error so it's giving us one result back i'm going to basically just copy that and set this equal to and we'll open the brackets as if this was a closure and we'll paste in what we're getting back here and then we'll say in and now i want to give this an actual local local name like we do up here so this result let's call this return the result just like it is and if we do finish let's just print and let's just say returned result and we'll pass in the returned result here getting a quick error message because query result block is only available in ios 15 and my app right now is built for ios 14 as well so we're going to add in this fix so those of you who have never seen this before basically when you have some code that's only available in certain operating systems like this is only available in ios 15. we can add this if available so that for users on ios 15 will go into this block and all the other users will go into this closure so if we don't have this query result block we then have to use the query operation dot and it's called query completion block and if i hold the option button and click on it we can see that it's giving us back a cursor and an error the only difference from the last one to this one is that these are actually coming back as two separate values rather than a single result so i'll copy that and in here we'll set this equal to the closure and we'll paste this and we'll say in and see so now this was one single value as a result here we're getting two values so this will be the returned cursor and this will be the returned error all right and again we're not really going to do anything with this let's just print out returned and let's just say query completion block and let's actually change this to query result block so we know which one we're coming through i believe my simulator is running ios 15 so we should get this back as well so we're almost done but the last thing that we need to do is actually before we get this completion we actually need to add all the items that we are fetching into this operation so it's going to work just like this except we have different blocks all right and we are almost ready to actually fetch these items so right now if we ran this it would query on all the fruits it would create that query that actually finds all the fruits and then and then with this result it would return us a success but it won't actually return us any of the fruits because we actually need to manually add some logic so that as we're doing this query we actually add the fruits so we can actually get them back so just like this we need to create two more completion blocks so up here let's call query operation dot record matched block so this block is called every time we hit one of those records so let's hit enter i'm going to hold the option button and click on this we can see this gives us back a record id and a result so i'll copy that set is equal to enclosure let's pass in that and we'll say in so this will be our returned record id and this will be our returned result now from this return result we can actually get the actual record that we are on here so when again this is being called every time we hit a record that's in our database so here let's switch on let's create a switch statement and we're going to switch on the returned result and we're going to say case dot and results are either going to be successful or failure and we can see that if we are successful we're going to get back a ck record in that success so we'll say success let record and let's just break for a second and then we'll say case.failure let error and for right now let's just print out uh the error so here i'm just going to print error let's put in the record match block and let's just print out the error we don't need a default case here so in here we have this record so let's try to get the name from that record so we'll say guard let name equals record and i want to access the key inside that record so when we went to add our name we added a key that was a name i'm going to copy that key exactly and let's reference the key and we'll make sure that that key is a string so we'll say as a string else return so if that record for whatever reason does not have a name even though we know all the fruits have names then we'll just return out of this closure if we get a name we then want to do something with that name so as we create this operation we run through all these loops we're going to create a array for all the fruits that we get let's say var maybe returned items of type and it will be an array of string and let's set it equal to a blank array to start and if we can get these names let's call returned items dot append and we'll append the name all right we're getting another error here because this record match block just like down here is only available in ios 15. so let's fix that quick and our fallback we're going to call query operation dot record fetched block if i hold the option one and click on record fetch block we can see that this is only going to give us back the record we're not getting the result and the id just a record directly so let's set this equal to a closure and we'll say returned record in and now what are we going to do with this we're going to do the same thing we do when we get this record so i'm just going to copy this paste it down here so if we get the record here let's just make sure we get the name and then append it to our returned items all's good this should be returned record and so now as we are running our query operation it's going to go through all it's going to find all of the items that have record type fruits as it goes to each item in the database it's going to run this record match block so it hits each item it gets the record we're going to get the name and then we're going to append the names and now we want to actually return these names uh when we are done with this function so we could return it right after we append it but every time it hits a new item it's going to then be appending and returning appending and returning and that might not be a good ui for our users so we want to actually return these items at the end of our query which is happening actually in the completion blocks at the bottom here so in this completion block when we get this we then want to add these returned items to our app so up in our top review model let's create an app published var let's say maybe fruits of type array of string is that equal to a blank array and then when we get our completion block here let's call let's make this a week reference week self let's call self dot fruits equal and we'll set it equal to these returned items same thing in this closure we should also make this week and now with all of that done we can finally actually fetch our items so a lot of code to fetch the items but once you get the hang of this it's pretty straightforward let's call fetch items so i'm going to come back up here and let's create a init and let's call fetch items when we initialize our view model lastly let's put these fruits on the screen so i'm going to come down here and we have a list and in the list let's do four each open the parentheses and we are going to use the id completion here we're using the id because we are looping on vm.fruits which is an array of strings and those strings we can identify by their hash value which we're going to use by calling backslash dot self that'll get the hash value for each string and this will be the content so in here let's just put a text and we're going to use the money sign to zero for each string that we are looping on let's run our app one more time and when we initialize that view model it should fetch the data awesome just like that we have orange coconut apple peach on the screen here we can see the print out returned query result block and it looks like i forgot to go back to the main thread again so let's actually dispatch q so let's actually add a dispatch queue domain async let's put in our code here i uh keep forgetting to do this let's do it down here as well i keep forgetting to do this because i i'm so used to writing a combine code and obviously this is not combine this is just using escaping closures and we may or may not be converting these into combine in a future video in the series but i'm not going to talk about that right now a couple things while we're here on this fetch request i want to point out so coming back to this predicate here so on this query we can actually also add a query.sort descriptors and we can then sort the query so right now we're just getting the data but we can actually sort it before we get it and this needs to be an array we can see here is an array of ns sort descriptor so let's just add one quickly ns sort descriptor open the parentheses and i'm going to pass in a key and ascending uh and ascending and here we need to add in what field we want to sort by so let's do let's sort by name right now and let's make it ascending let's run the app one more time and we can see now we got our same fruits back except they are in alphabetical order we could do descending let's make it false let's run it again it's in reverse order and we can sort by pretty much any field inside that record so if i call here so if i look down here at this record and i call record dot uh we can see that we also get a the creation date back the creator user id last modified so we can sort by any of these so i'm going to do the creation date so let's sort here by creation date and delete this and let's do creation date ascending false so let's see what we get here and now and now this was a good thing to point out actually uh we get this error message down here that the field create time is not marked sortable so let's go back to our cloud kit container here and we're going to go to the indexes and we're gonna go to the fruits and just like we had to do for the record name right now we wanna right now we are sorting on the creation date so the creation date uh is the created timestamp i don't know why the name is slightly different here but it's the created timestamp and we're going to make it sortable so let's save those changes let's go back to our app here all right let's let's run it one more time and when we get this we should see peach is at the top of our list now uh so peach was the last item that we created and our sending is false so the last item should be first if i go to the database and look at this we can see that peach was actually the last item that was created so our sorting filtering is actually working perfectly while we're on this sort i do want to point out to you guys that right now we're getting this array of returned items right so we are basically when we're done we're just setting fruits equal to the returned items so we could of course just call dot sort like we do in like combine and things and we can sort on the items on the app directly so after we get all of the fruits back and we want to sort them we can do that just fine that's totally fine but what we want to point out though is that this sort is sorting this sort is sorting the query not the returned items so if we were querying on let's say we were querying on a very big database of a thousand items and maybe our query is only gonna get the first 100 items well if we didn't add this sort and we just got items and then sorted it it would be 100 random items in the in the database here we are sorting the query so it would then first sort the items the database and then give us back the first hundred so it is important to just think about uh do you want to actually sort the query or do you want to start the or do we or can we just sort the items after we get them on the app and on that same note we can also call query operation dot results limit and we can literally give it a limit on how many items we want to get back from the database so if we only want to get two items i can run it and it's going to do this sort and it's only going to give us the first two that it's only going to give us the first two back so same thing now we just have peach and coconut now if i click and hold if i hold the option button and click on results limit we can see that for most queries we can leave this as the default value and it's going to give us the maximum results and if i click on the maximum results it's going to take me to the documentation and it says this value the value of this doesn't correspond with the actual number of records cloud kit dynamically determines the actual number of records according to various conditions at runtime so this is super annoying if you don't know about it because you think if you're querying on something you're going to get all the items back but cloud kit is actually going to limit the number of items we get back even if we don't specify a maximum number of items and you could play around with it but it turns out that the maximum items you can get back from a cloud kit query at least as of today is a hundred items so even if we have a thousand items in our database or more than that and we do any kind of query and even if we don't give it a limit it's only gonna give us back the first hundred so that's where these uh cursors come in and we get a cursor from this returned result as well so basically the cursor we can use to continue the query so we could so we could then get the first hundred move the cursor forward get the next hundred move the cursor forward and so on and so forth until you get all your data i'm not gonna do that in this video because that's probably a whole video on its own i'll cover that in the future but i just wanted to point that out to you guys before you get confused on why your database is why your queries are limited to a hundred results so let's comment out this operations result and last thing i want to point out here is the predicate we can also use the predicate basically to filter on the results so before we get all of the fruits if we want to get a sub sector of the fruits and we want to filter it first we can use a custom predicate so i'm going to comment this one out and let's say let predicate and let's set it equal to an ns predicate open the parentheses i'm going to use the one with the format and arguments or is it arguments it's argument array sorry so we want the argument array which we can put in any type here the arguments we need the cva list pointer so we want the arguments array and then here we need to add in a specific format for ns predicates and if i hold the option button and click on this we can get some data it gives us a little bit of examples here on how we can use this and we can even go and click on the predicate programming guide it's going to go really into detail on how we can use these ns predicates now i'm not going to go into detail in this video these are the same predicates that we use in core data which i covered a little bit in the core data section of the last playlist but basically we can do something like now our fruits only have a name so we're just going to filter on the name so we'll say where the name and this is the exact key that we have in our fruit record equals and we're going to do the percent and then the at sign and then in here we'll pass an array of and let's add in maybe coconut let's run the app one time and we should now even though we are even though we are querying on all the data we should only get back the coconut and we don't have any kind of result limit but we're only getting back coconut because we filtered for it basically uh and this doesn't make much sense to filter on the name of an item but if we had more complex data and maybe we had uh like categories in each of these so maybe we had like maybe it was all just like grocery items and then some items were fruits some items were vegetables some items were produce some items or something else we could then query on like one field inside those being the category or whatever it is i just want to show you guys how we can do that i'm going to comment it out and you can play with that on your own time but let's comment this one back in let's get all of our fruits coming up here and we are rocking and rolling through this video and i want to just wrap up this video with updating records and then deleting records so uh unfortunately it is a bit more code that we have to write i know this is getting longer than i had expected but um let's create another func called update item open close parenthesis open brackets and when we go to update an item basically all we need to do is the same thing we're doing in our ad item so we get the record except instead of creating a new record we just take the existing record we access that key and we change it to whatever we want and then when we're done we just save it back to the database the caveat here of course is that we need a reference to the actual record so right now as it is right now we're just getting fruits and once we get there the name of the fruit we don't have the actual record that that fruit is coming from so really what we should do in our app is create a custom data types let's create a struct and let's call it fruit model open brackets let's conform to hashable and in here we obviously want our names we'll say let nama type string and let's also just pass in the record the record of type ck record so when we create fruit models we're going to pass in a name and a record so take this and we're going to loop on fruit models then we should get some errors in our code now so coming down here the returned items right now is an array of strings let's make it an array of fruit model so here we will need to pass in a fruit model open the parentheses with a name and we'll pass in the record here as well we'll add a fruit model with the name and the record or returned record and coming down here uh right now we this will be the fruit model so we want to access the dot name inside the fruit model and then finally we're going to call on tap gesture so when we tap on a name we're going to call update item which we want to pass in a fruit of type fruit model so we'll say vm dot update item we should call it update fruit and let's pass in the money sign zero which is the item that we are looping on if this is confusing you guys this is actually for fruit in and then this could be the fruit and then finally we can call our update items so let's access the records we'll say let record equals fruit dot record and we'll say record and then we'll access the name field and let's just set it equal to some random name for now so uh obviously we want to we would want to add in some kind of text field in our app but let's just add a new name and then we'll call save and we also want to save the record i'm going to run the app one more time i'm going to tap on the word peach you can see something printed out here it says new name the ui did not update because we did not update it yet but let's look at our database quickly and uh so we have peach here but if i if i click it and i reload it let's reload it quick we can see that there actually is a new name so we updated our record it was that easy we could take any field and just give it a new field and save it back down to the database and of course we want to actually update the ui after we do it so there's two ways pretty much to do it the first way is after we call save item we can just refetch all the items so in our save item function we can just call self dot fetch items we'll refetch so let's run it again let's click on maybe the orange this time and we updated with our new name we refreshed all of our data this is okay when we have relatively small apps and small data that's coming through this fetch but if you are in a bigger app the better way to probably do it rather than fetching all of the items again would probably just be updating the current item that's in your array on the screen so after you update it you know the database is updated and then you can just manually update within this array i'm not going to run through that but uh you guys know it's there and let's wrap up this video with one more funk delete item on close parentheses open brackets and we're going to use uh on the list and we're going to use that handy feature on our list so on this for each we can call dot delete on delete and then of course this is going to give us an index set so in our delete item we're going to pass in an index set of type index set let's say guard let index equals index set dot first else return so this will be usually it's just it almost is always just one single index inside the set then we will call let fruit equals fruits our fruits array we'll access the item at the index and now that we have this fruit we can get the records we'll say let record equals fruit dot record finally we can call ck container default dot in the public cloud database and then of course we can just delete and just like before the delete we either need to pass in a record id a subscription id or a record zone record id and let's pass in the record dot i record id and we'll get our completion here and we'll say returned record id and returned error and if this is successful we then want to actually update our ui as well so we could again then just go and fetch refetch all the items or we could just remove the item from the array manually so we could just call fruits dot remove at remove at and then we can pass in the index and that should remove it let's make this a weak self i'm not gonna do any checks to make sure this is working uh if there's no error it worked this should be this index and this should be optional and let's try to call from our view here called vm.delete item run it on the simulator one more time let's take this new name here and delete it and we forgot to and and we're getting that error again on the uh because we deleted from the background thread so let's dispatch q dot main async pass in our fruits let's run it one more time all right let's delete this new name and it's working perfectly if i go back to our database and we reload it we should have only two items left in our fruits and there's only two here so our database is working in real time and we have now gone through all the crud functions that creating reading updating and then deleting uh one thing i do want to point out here for those of you who are gonna not watch the rest of these videos i highly recommend you keep watching this cloud kit series because we're going to continue off of this i do want to just point out uh because we added the ck record directly to our free model here and that's okay for this app because this app is only using a cloud kit but sometimes you might have models in your app that you might not want to be tied to this ck record because if you're using these models maybe you're only using cloud kit some of the time or maybe you're using some other database that doesn't also support cloud kit you don't you might not want these free models to be tied to cloud kit so in the actual documentation that apple gives us for remote records now we haven't gotten to remote records in this video uh i'm not even going to get into it in this series but in this documentation i just want to point out that apple does uh give us some details about if we want to integrate these cloud kit records into an existing model their recommendation is basically to take the record and encode it and basically convert it into the records metadata and then we can store the metadata inside our fruit rather than the actual ck record and then we could here we can un-archive it and get the ck record back from that metadata i'm not going to go ahead and do this because we don't need to do it in our app but i just want to point it out because you may or may not want to actually keep that ck record inside your data model all right guys that's enough for this video we have done crud functions in cloud kit i hope you enjoyed it hope you're able to follow this tutorial i know there's a lot of code here we're going to start cleaning up some of this code in one of the future videos uh but for now hope this was enough to get you guys going all right thanks for watching as always i'm nick this is swiffle thinking and i will see you in the next video [Music]
Info
Channel: Swiftful Thinking
Views: 797
Rating: undefined out of 5
Keywords: Cloudkit functions, cloudkit container, cloudkit database, how to use cloudkit, cloudkit ckrecord, what is cloudkit, what is cloudkit ckrecord, set up cloudkit, cloudkit swiftui, swiftui with cloudkit
Id: A-1U_iXiCyI
Channel Id: undefined
Length: 53min 39sec (3219 seconds)
Published: Tue Nov 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.