The course is part of this learning path
In this course, we explore what widgets are and how to work with them. You'll learn what a widget is and how you can leverage them in order to provide an optimum user experience in your apps.
Hi, within this lecture, we're going to save this hero when a user taps on it. Okay, so whatever hero our user taps on will be saved to our user defaults. So, in order to do that, first of all we need to implement an onTapGesture over here so that we can actually understand where user has clicked. So, if you say .onTapGesture, so we can write the code over here, but we can get rid of this count because we only need one. So, whenever user taps on any hero it will be saved. So, we don't even need that, just delete it and open a new curly brace and you're ready to go. So, whenever we write between those curly braces will happen, then a user taps on one of these superheroes. So, in order to save this, I'm going to create another function inside of our struct and I'm going to call this saveToDefaults. Okay, and for right now, I'm just going to ask for a hero which is a superhero, and we're going to get this hero from the four each loop. Okay, so for right now I'm just going to print the hero. name or image. It really doesn't matter just to see if this works or not. And I'm going to say saveToDefaults over here, it will ask for a hero and hero will be the hero in the four each loop, right? So, this should give us the clicked hero. So, let me run this on our simulator and see if we can get the name of the hero, wait until it's finished and then you can just click on the one of the heroes and see if it actually shows us the name of the superhero on the logs. So, let's wait until this is done, and we're going to see how it looks like on the simulator as well. I believe we haven't tested it before, so it's taking some time but finally it's opened. So, let me click one of these things. Here you go, Superman, Batman, and let's try the Iron man as well. So, we see the name of the superhero. Now it means that our onTapGesture is working. So, we get to do whatever we want to do under this saveToDefault function. So, over here under the saveToDefaults function, what we want to do, we want to get the hero and just convert it into a data, and then we're going to save it into the user defaults. And in order to do that, you can just use the old user default string, which won't require you to have a developer account, but I wanted to show you the AppStorage property wrapper which came with this with UI too. So, this came in late 2020. So, we need to learn about it as well. So, I'm going to show you the AppGroups, the AppStorage, and it will require you to have a developer account, again, if you don't have it, it's not mandatory to create widgets. However, it will be good for us to learn about this as well. So, you can take notes if you don't have a developer account or you can just try to write the code with me but you won't be able to save it to the user defaults just by implementing what I'm about to implement. So, let's go to project settings and let's see what I'm talking about. If you come over here, if this is not open, you can open it with clicking on this left hand pane and you have to select the targets and go to the 'Signing & Capabilities.' So, we're going to add a capability to our project which will be AppGroups. So, if you click on this capability, you can see the different kind of capabilities in the list, and we want this AppGroup, okay? So, this will allow access to group containers that are shared among multiple related applications. We're not going to create another application, but we're going to create another target within the same application which will be our widget, right? So, it has to actually talk to each other so that our AppStorage and everything will be synchronized. So, in order to do that, just open this. Okay, just select the 'AppGroups' and copy your bundle identifier because we're going to need it. Just select it and do command C, and if you click on the 'plus' button, it will ask you to add a new container which will be prefixed with group. and you can paste in your bundle identifier. So, this will be our AppGroup identifier, our container. So, group.com.yourname.yourappname, okay? So, if you say Okay, it will appear in here and it will create a provisioning profile for you, this is exactly where you need to have a developer account, okay? So, click on this refresh buttons until you don't see the red lines, okay? You don't see the warnings or errors? It will go away and then you will be ready to implement the AppStorage string. So, now we have an AppGroup and we're going to add the same AppGroup to our target later on so they will be connected. So, let me come back to our ContentView, and here we're going to create our AppStorage which is a new way to reach the user defaults. So, in order to do that, you can just say @AppStorage, and here you go. As you can see from the details of the description over here, this is a property wrapper and this reflects a value from user defaults, okay? So, this is very easy to work with and it makes working with user defaults very easy as well. So, we're going to see how to use it, but we can we should start with this @AppStorage property wrapper in order to define it. And when we open the parentheses, it will ask for a key, okay? It it will be a string and a store. So, what key should we use to store it and where should we store it? Okay? So, choose this option and for the key, I'm going to go for a hero. It really doesn't matter what you use over here, but it has to be exactly the same when you try to retrieve the data as well. And for the user default, I'm going to create a user default from here. It will ask us for a suiteName, and for the suiteName I'm going to give the group string that we have created AppGroups suiteName, okay? So, I'm going to AppGroups container name I mean. So, I'm going to paste in our bundle identifier and prefix it with the group. okay? So, group.com.yourname.yourappname. Of course, we're not done here because this is just a property app and we we need to write a variable under it as well. So, I'm going to call our variable a heroData. So, this will be a data not date, okay? So, this will be equal to new data. So, this data will be stored in the AppStorage in the UserDefaults, and all we need to do now is to change the value of this hero data, that's it. That's how you save something into the UserDefaults by using AppStorage property wrapper. This makes the whole process very easy once you get to know it, okay? So, since we have this heroData, we can use it under the saveToDefault function. So, I'm going to comment this out and I'm going to convert our hero to data, and I'm going to do it with if let because something might go wrong here. And we're going to use JSONEncoder right now to encode and change it to data. So, let me show you why we are using if let. If we say JSONEncoder.encode as you can see it throws and error. We're going to, of course, use a try before we do that, but also we can use if let to make things safer. So, I'm going to encode the value. The value is the hero, okay? And we're going to try and encode this because this will throw an error as you can see. And in front of this I'm going to write if let heroData = try? JSONEncoder().encode like this. So, let me close this down so that we can have a better space over here. So, let me just do it like that and open our curly braces and it should be fine. So, if this works out then we're going to have our heroData. So, I can just change the self.heroData which is our user default variable here, okay. AppStorage variable and I'm going to make it equal to heroData. So, heroDatas are conflicting over here, like maybe it's confusing so you can choose another name, but for right now it's good for us. And here we go, that's all you need to do in order to save this to say user defaults, right? It's very easy actually. So, I'm going to run this, okay? And let me print this as well so that we can understand if this is being like executed, if this actually proceeds under the if let, if this succeeds in encoding into jSONEncoder into data, and here we go, it prints out the names. So, this is definitely being saved into the user defaults if we didn't anything wrong and I believe we didn't do anything wrong, but we're going to see it when we create the widget. Now, finally, we are done with the functionality of our app. We're going to create the widget in the next lecture.
Atil is an instructor at Bogazici University, where he graduated back in 2010. He is also co-founder of Academy Club, which provides training, and Pera Games, which operates in the mobile gaming industry.