Setup CloudKit in SwiftUI project and get user info | Advanced Learning #21

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 this section of the playlist we're gonna switch gears a little bit and jump into the wild world of cloud kit now when i first started recording this there was so much that i wanted to cover because there's so many cool things in cloud kit but i realize it's too much to just throw into part of this playlist so in the future i'm going to actually make a full on cloud kit playlist but for right now we're just going to touch on the basics set up a basic cloud kit container do some basic crud functions and kind of just cover the most common features in cloud kit so in this video we're going to set up our cloud kit container we're going to connect that to our app and then we're going to get some data on the current user after they're connected into cloud kit and we are back what is up everyone i'm in xcode and we're going to cover cloud kit in this video of course so just want to reiterate one more time that if you don't have a paid apple developer account unfortunately you cannot use cloud kit you could though still follow along write down all the code obviously it's not going to actually work but this is definitely useful code to have and at the end of this little cloud kit segment we're going to actually create a little utility class using some of our cloud kit code and in doing that we're going to use a bunch of the previous stuff we've learned in this course like generics and protocols and i think it will be a really good hands-on uh example for you guys so even if you don't have cloud kit i would obviously recommend uh just following along anyway with that said let's just jump into this so again we have a couple videos here with cloud kit so i'm going to create a folder let's right click the navigator create a new group and let's just call it cloud kit bootcamps and inside that folder i'm going to right click create a new file it will be a swift ui view and let's call this cloud kit user boot camp and let's click create all right and we're calling it user because in because after we connect to cloud kit we're going to get the current user's info we're not going to actually set up our full database in this video that's going to be the next video so before we actually write any code let's connect cloudkit to our project let's go to the navigator here let's click on the your app target up at the top here or you're at project in the navigator and inside to this navigator here let's go and click on our app target so this should be your main app target not your test targets so we have the main app target here and then we're going to go to the signing and capabilities tab and this is tab where we can add a bunch of capabilities to our app and we haven't used this very much because we've been mostly just writing swift ui code but in here we can click plus on the capability and then we can add some capabilities to our app and you'll see some really cool stuff in here we can add maps we could add a home kit health kit a bunch of cool stuff that we have not used in these courses yet but one of the things that we want to add is cloud kit and you can see here that i'm going to type it in and i have no matches and if you have that that probably means that you're not signed in to a paid apple developer account so right now i'm not signed into a paid apple developer account and nothing's coming up here this is apple's way of telling us that if you don't have the paid account you can't even access the button to try to add cloud kit to our to your project so what i'm going to do is just quickly switch to a paid apple developer account i have an old account here and then i'm going to go back to the capabilities and icloud is now popped up so all i have to do is double click it to add that capability to our project i have a little error message here that hopefully you don't have basically uh in making this course i already created a cloud kit container with this bundle id and you can only have one cloud kit container with the same bundle id so i'm just going to change my bundle id for this project quickly and let's do a com. swiftful thinking and your error should go away and then in this icloud section we want to check key value storage this way we can use keys and values kind of like a dictionary to actually store values in the database and of course we want actual cloud kit when you click on cloud kit because you can because you can send push notifications through cloud kit we should also get the push notifications capability added to our project the next thing we want to do is create a container for our app so if you have never used cloud gig before this will be empty but i have some previous containers here we're going to create a new one a container is essentially a database and the reason it's putting this here is because we could build multiple apps using the same container so this is where if you were building multiple apps and you wanted to reference that same container or database you would just check the same one but obviously we're creating a new one so let's create so let's click the plus sign here and we want to give our container a name now as i was saying before we can't you can't have two containers with the same name in your cloud kit and there's also no way to delete a cloud kit container at this time i don't know why that is but there's no way to delete a container once you create one so we really want to use a unique identifier for this so what i'm going to do is just use my bundle identifier i'm going to copy it and let's just use that as the title for our cloud kit container let's click ok it's going to set up a new container you should have that you should have that pop up here i'm going to click the refresh button here to make sure that this turns white basically reload it make sure that container is set up if the debug version if you get a little pop up here with a debug version of icloud i'm not really sure why that happens but you can just uh x out of that debug version and then it will remove the capability and then you can just press plus and add the capability back again but basically we want to get to this spot where we have uh your container and the text is white and not red and now that we have that we have this handy dandy button here to go to the actual cloud kit console this is my favorite part of icloud because i it's on the internet so normally you have to like go to the website and find it but apple's giving us this awesome button it will just pop up right to our cloud kit container and you'll have to sign in to your apple developer account once you're inside here we got some different tabs that we can click on uh telemetry is kind of like analytics uh we've got logs settings we're going to go to the cloud kit database and you want to make sure we are in the database for this app so that's uh this should be the bundle id that you just added uh if not you can click on this and then it should pop up all all the different containers that you have inside your cloud kit i will note though that sometimes these containers take a couple seconds or even a couple minutes to create i've made this before and then like ran into a situation where it wasn't showing here uh basically i just had to walk away from the computer come back five minutes later and then it popped up because when we create this container it's literally creating an entire database in the cloud so i guess that takes uh more than a second sometimes all right and we're gonna obviously jump into this as we start using the database just to go over some of this really quickly inside your cloud kit container there are actually two databases there's a public database and a private database the public database will be shared by all the users in your app so most of your main app data is going to go there the private database is private to the current user and their cloud kit account so so generally in the private database you're only keeping stuff that's going to affect the current user and the current user has the ability to actually share their private data with other users so if there's like a family plan or something like that you could keep some data into the private database but generally if we're talking about apps and like and social networks where people are sharing data everyone can see each other's data all that stuff is going to go into the public database so in each database we have record types and these are basically your data models your types of data that you are storing inside cloudkit obviously we don't have any right now but in a second we're going to upload some stuff and we'll have some data here there also are zones in cloud kit which we're not going to get into in this short little series but zones are basically so right now i guess it just gives us the default zone uh zones are basically sub sections inside a database so we could go in the private database and we can add more zones and it's basically just a way to segregate uh the data that's in the database you can think of zones sort of as folders so when you store data into a zone it's separate from the other zone and the reason we could do that is so that when we go to share when we go to share some data we could share an entire zone and not share all of the data from a user something like that we also have subscriptions here which are basically listeners on the database which we can then use to fire commands to the iphone so subscriptions we're going to use to actually trigger push notifications moving down here we have indexes this is basically uh anytime we want to query on our database whether we are searching for something querying something filtering something we'll have to add an index to do that record types is all the types right now i guess we just have users even though we don't have any and then there's security roles where you can grant certain people certain act different accesses to the database and of course we're going to be working in this development container but there also is a production version of this so before we actually release our app we want to we're going to want to deploy the schema changes to our production version so this is also a handy feature because we can do some testing in our development version and not have it affect our live users and then and then once we're ready we can send that to our production version well with that said let's just jump back to our xcode and finish connecting it to cloudkit here so i'm going to go to our cloud kit user bootcamp all right let's create a very simple class let's call it cloud kit user boot camp view model make it conform to observable object let's open the brackets let's initialize one inside our view with an at state object private var vm equals cloud kit user boot camp view model i hope you guys are getting used to these view models now it's definitely a good habit to get into uh inside our init of the view model we're going to call a function let's make it a private func and let's call it get icloud status open close parenthesis open brackets let's call it in our init in order to actually use the icloud framework we need to first import cloud kit all right and now that we have cloud kit imported here we can actually go ahead and use the framework so let's call ck container that's our cloud kit container dot default our default container and let's call check and let's call account status so if i hold the option button click on account status we can see that this determines whether the system can access the user's icloud account so in order to use icloud the user also needs to be signed in to their icloud account on the device so not only do you need a paid apple developer account to use cloud kit but the user needs an icloud account to use cloudkit now personally i would not be worried about that because pretty much anyone i know that's using an iphone has an icloud account it's one of the first things that you set up when you get an iphone if the user is using any sort of uh apple cloud they have an icloud account but of course we can't just assume that and the first thing we want to do is check that the user is actually signed into their icloud account so we'll call account status and then we'll press enter on the completion here and we're getting back a status and a potential error so let's call this returned status and returned error all right and i believe this line of code this account status is actually going to happen on a background thread so before we update our ui we actually want to return back to the main thread it's called dispatch queue dot main dot async and in here let's uh let's switch on the status so we'll say switch on the returned status and let's press the period here and we're going to get a bunch of different results that we can get back from the status so let's just do uh available and let's break for a second we'll do case no account break case what else could not determine break case restricted break and then let's just leave in our default and let's break for a second and for this video depending on what the status is let's just put the status onto the screen just so we can see what's going on here so so at the top here let's just create uh two variables at published at published var let's say is assigned in to icloud of type bool started as false and let's go at published var let's say error of type let's make it a string and we'll set it equal to a blank string to start and let's just put these on the screen so down here i'm going to put the text inside a v stack the first thing let's say in the first text let's just say is signed in colon and let's return the vm dot sign into icloud.description maybe.uppercased and below that let's just put another text with our vm.error if we have one all right and coming up here let's get rid of these breaks now so i'm going to create a custom error for each of these so let's create an enum let's call it cloud kit error let's call it cloud kit error i mean conform to localized error and let's do case icloud account not found let's do let's do case icloud account not determined case icloud account restricted and let's just do case icloud account unknown so if we get no account let's set self.error equal to cloudkit error dot no icloud account not found let's do localized description let's also make this a weak reference to self because we are using asynchronous code here so this will be optional and then could not determine let's do another error this one would be icloud not determined and this one will be icloud restricted and then the default will be icloud unknown all right if it is available let's just set self dot is signed into icloud equal to true all right let's go and run our app on the canvas here i did notice when i was testing this that occasionally i get this spinning wheel of death here i'm sure you guys have gotten it too uh the preview can't load right now this is super annoying in xcode 13. i don't really know why exactly this is happening but i find it happens sometimes when we use these external databases or frameworks like cloud kit it also happens when i use firebase so what i'm going to do is actually go to the editor window here click on canvas and i'm going to uncheck automatically refresh canvas this is a convenience thing so that when we're typing in swift ui the canvas will automatically update but instead if i uncheck this it'll just update when i go and click refresh so if i click try again hopefully this will work and for whatever reason the canvas was not loading for me so i shut down x so i closed out of xcode i restarted xcode and when i came back and it opened up the canvas is working again don't ask me why that is you might have to do it too i do not know why all right so once you get the canvas going here you should see an error message so sign in is still false so obviously we did not get that available message uh but what we are getting back is that cloud could error error zero which should be our first error here let's actually just change that up quickly let's make let's have this enum have a string value as a raw value and let's just use the raw value instead really we should create full errors for these in our actual app but i'm just trying to get this on the screen here so let's run it one more time all right icloud account not found so the device right here this simulator is not signed in to icloud so what i'm going to do is actually build and run this to a simulator so that we can sign into icloud on the simulator so let's take our cloud kit user bootcamp view and let's go to our app.swift file this should be where your main call is and then let's just make our cloud kit user boot camp the first screen in our app i'm going to go back to our screen here and we don't even need the canvas for the rest this video we're going to use a simulator i'm going gonna close this out and let's build and run our app now to an actual simulator alright so we should still get the same error except we can now fix it because we're on a simulator we can sign into an account all right so i'm here and we get icloud account not found so this means that the user on this device is not signed in to an icloud account on their device uh so this is the first thing again you want to check when you're using icloud and almost always users are going to be signed in but if they're not you're probably going to want to show some pop-up at the start of your app that says hey you need to sign into your icloud account in order to continue or something like that so let's go to i'm going to close out of the app on the device here i'm gonna go to the settings and we need to sign in to your icloud account on the device so i'm just gonna sign into my personal icloud account and i'm not going to merge my contacts to this device and now that we're signed in we can actually use the app with a cloud kit so i'm just going to stop it let's run it one more time to the simulator and at this time we should at least not get the same error message so now we are actually signed in all right so once you sign in to icloud and as all of your users begin to sign into icloud let's go back to the console i'm going to reload the console and we should actually start to see some users popping in here so i'm going to click on users and i'm going to try to query the records and first of all queried type is not marked indexable so what on earth does that mean so as i mentioned before in order to search something in the database we need to create a query for it or we need to create a query or an index for it so i'm going to go to my indexes here and we have our users of course our users type but there are no indexes here so let's go and add a basic index and i want to query users by their record name so let's make it queryable we could also make it searchable or sortable which is super handy let's make a queryable let's save those changes let's go back to our records area of the database here let's go to our users and now we should be able to query records and you might have to reload the page because it might take a second to actually update but now that you are signed in on the device we should have one user in our database and we can actually go ahead and click on the user to see all of their info now one thing i want to point out while we're here is that the users in cloud kit is not the same as your typical user that you have in your database so if a user is opening your app and they are creating a profile with like a bio and a profile image and then other users are going to see that profile that is not the same as this user these users that auto populate into cloud kit are just basically the icloud accounts that are connected to your app so it's important to understand the difference i definitely got confused when i first started using cloud kit because i thought this was my actual users but really these are just the icloud accounts so if users are making profiles you're probably going to want to store those in their own kind of record type somewhere else this is just keeping track again of the icloud accounts which comes really in handy when we start using zones and private databases and things like that we can see here this user has basically an auto generated id they're in the default zone we can see exactly when they created the account and we can see the last time they modified their account which is pretty which is pretty cool and it's really handy that this is all auto populated for us we're not going to actually change the account so i'm just going to x out of here i wanted to show you guys that once users are connected we can then see them in our database all right so we are now connected to icloud of course and oftentimes once you get a user actually connected to your cloud kit that you then probably want to pull some of that user's information because from their icloud account we can actually get their user's name automatically which is really convenient for our users so instead of having to ask instead of asking them to type in their name we can just fetch it from their icloud account so let's jump back to xcode here and let's go full screen and we're gonna create another function let's put it down here and let's create a quick function called discover icloud user discover icloud user and in here we're going to call ck container our cloudkit container.default.discover user identity and we can see here we have some convenience to discover multiple users or a single user and in order to look up a user in our cloudkit database we either need a their user record id their phone number or their email address and of course at this point in our app we don't have a phone number or email address so all we have is so we're going to have to use a record id press enter here and the record id is of type ckrecord.id so let's pass that into this function we'll say id of type ck record dot id i'll pass in the id here and then we're going to get a completion handler which will give us which we'll press enter on this will give us a potential user identity and a potential error so we'll say returned identity and returned error all right so again this is happening i think on a background thread and it's asynchronous code so we want to use a weak reference to self and in here when we update our ui we want to go back to the main thread with a dispatch queue dot main dot async and let's try to get the user's name from their identity so we'll say if let name equals returned identity dot name components and then inside the name components we can access a whole bunch of different i guess versions of the user's name so we have their given name middle name family name nickname and this is going to be whatever they have loaded into their personal icloud account so i'm going to use the given name most people probably don't have most is filled in so if you can go through these on your own time and most of them are probably going to come back nil but i believe almost everyone has a given name and a family name so give a name if we can get it let's then put it on the screen so i'm going to create another up here let's do an add published var let's say uh user name of type string and let's set it equal to a blank string and in down here we're going to set self dot user name equal to name and now we want to call discover icloud a user but of course we can't call this unless we have a ck record id so we need to run another function to get their id before we can actually run this function let's create yet another func let's call it let's call it fetch icloud user record id open close parenthesis open brackets and we're going to call again ck container dot default dot fetch user record id if we hold the option button and click on this we can see that this fetches the user record id for the current user so we can only call this for the current user so we can only call this for the current user not other users which is exactly what we want and i also just want to reiterate that we can only call this if the user is actually connected to their icloud account so if we didn't first connect to the icloud account we wouldn't be able to actually call this so in here let's press enter this will be returned id and returned error and if we get an id we want to then call this function so we'll say if let id equals returned id and then let's call this function so again we need to reference self so let's make a weak self and we'll say self dot discover icloud a user and we'll pass in the id let's call this function this fetch after we get their icloud status so in the init here i'm going to call fetch icloud user record id and let's finally let's just put the username on the screen if we get it back so coming down to our view here let's put another text let's say name colon and we'll call vm.username the username is going to start off blank we might even get an error on this build but let's see what we get so i'm going to build and run this to the simulator again and the name is clearly not coming through and that's because uh the name that's coming back is actually still nil because i forgot that we we still don't have permission from the user to actually access their identity so before we can even do this stuff we need to actually ask the user if we can uh access their info so let's go and create yet one more function let's call it request permission open close parentheses open brackets let's call ck container dot default dot request application permission uh in here we need to add a application permissions so i'm gonna make an array and i think there is only one that we can do i'm gonna press the period and it's user discoverability so we want to request uh to user discoverability and then we'll press enter on the completion handler here and this will be returned status and again returned error so let's put this status on the screen as well so i'm going to come up here and let's create a at published var let's say permission status of type bool equals false and then we'll set here we'll call dispatch queue we'll call dispatchqueue.main.async we'll make this a weak reference so weak self and we'll call and we'll say if return status is equal to [Music] let's say granted granted we'll say self dot permission status equal true let's put that permission status on the screen quickly so coming down here i'm going to say text let's let's say uh permission colon and then let's put vm.permission status all right now i think we are done writing functions for this video this is why i did this user stuff in a separate video so let's request permission before we fetch icloud user record id so we'll call it here i'm going to actually comment out the fetch for this first run and let's just request the permission right now so i'm going to build and run it one more time all right and so when we request permission we should get a pop-up on the screen do you want this app to look you up by email i really don't like the language of this but we can't change it unfortunately so basically this is allowing other people in the app that you have in your contacts to look up your user identity so this would be basically they can get your email your name and i think possibly your phone number don't quote me on that but if we want to actually get the current users data we need access to this so if they click don't allow and we run this discovery user identity it's just going to return nil so we should think about those edge cases if the user doesn't give us their actual name we don't have access to it we should then probably ask for it but for this tutorial i'm going to press ok to grant permissions so we see permission is now true and let's come back up here and now i'm going to call the fetch icloud user record id and let's build and run one more time and this time i got my name back and it says nick and notice that we did not type nick anywhere in this app all we did was run the app connect to icloud grant permission and then now the app has my first name and you guys can again play around with this but we can get more than just their first name we can get a bunch of other stuff as well i also want to point out here that in this return call in this return call for this returned identity we can also access returned identity dot lookup info dot phone number email address or user record id the caveat here is this lookup info is what you used to look up the user so because we're looking up the user with a recording with their record id we can then get back their user record id but since we're looking them up with their id we can't actually get this email this ad this phone number these will be nil if we instead look them up by email we would then get the email back if we look them up by phone number we get the phone number back so we so unfortunately we can't get their email address from this route right here but we can get their name which is pretty helpful all right guys that's it for this video we are connected to icloud we are signed into icloud we've granted permissions to icloud and we fetched the current user's name and in the next video now that we're connected we can actually start some crud functions we can uh really start creating our database we can add items delete items update items it's going to be a whole lot of fun but that's it for this one thank you guys for watching as always i'm nick this is swiffle thinking and i will see you in the next video [Music] you
Info
Channel: Swiftful Thinking
Views: 1,134
Rating: undefined out of 5
Keywords: swiftui cloudkit, cloudkit, what is cloudkit, how to use cloudkit, CloudKit swift, cloudkit swiftui, swiftui what is cloudkit, swiftui cloud, how to connect to cloudkit, cloudkit not working
Id: tww2vbJjXpA
Channel Id: undefined
Length: 33min 2sec (1982 seconds)
Published: Mon Nov 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.