Your First iOS & SwiftUI App: An App from Scratch

Feb 13 2023 · Swift 5.7, iOS 16, Xcode 14

Part 2: SwiftUI Data

18. Create a Model

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 17. Intro to App Architecture Next episode: 19. Conclusion

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

Okay. Let's learn how we can put the theory of app architecture into practice by creating a simple data model for Bullseye. To review, remember that we need three things. The target the user is currently aiming for, the current round and we need the total score across all rounds. These will all be integer numbers. Okay, let's open up Xcode and implement the Game Struct. Before we create our model, I want to do a little bit of organization of our files here just as a kind of nice practice. We can keep everything nicely organized this way. So open up the navigator with the button on the upper left and make sure you're looking at the first tab for the project navigator. Now, I'm going to click on the plus button in the lower left corner of the navigator and make a new group. I'll call this group models. This is where we're going to put our model that we'll be creating shortly, but let's sort the rest of this code that we have here as well. We'll create another group and we'll call it views. This time, select content view. Then right click and pick new group from selection. And name it views. Right now, we only have a single view in our app, but later on in this course, we'll be creating more views that will live in this folder. Finally, let's create one more group. Select the bullseye app file and the asset catalog and right click again and pick new group from selection, and name this one app. This is where you might put all the kind of boiler plate files and any other files that we need to create the app in general. I'm going to just minimize apps so I can just see views and models for right now. Now, I'll press command B, which is a shortcut to build the app and this is just to make sure that I haven't broken anything. I have one warning here but we'll worry about fixing this a little later. All right. So now our files are nicely sorted. We're ready to add a file for our game model. Right click on models, then click on new file, and that'll create a new file within that group. And I'm going to choose the iOS Swift file template. Click next, and I'll name it game. This is a Swift file and in the Mac OS finder, you would see it with a little dot Swift file extension. Xcode hides file extensions by default, but you can tell it's a Swift file because of the little Swift to the left of the name. This is mostly an empty file with just one line called import foundation. So we can start pretty much from scratch here. I'm going to delete this empty header at the top, but you can keep yours, if you'd like. Okay, so we're going to create a new game struct. So we do that by typing struct, and then the name, which in our case is game and follow it up with a pair of curly braces. It's a Swift convention that the names of types like structs and classes are capitalized, so make sure game starts with a capital G. Inside here we'll put the three properties that we need. The first is the random target value. So var for variable, which means it can change, and then we're going to put in target for the name, colon, and this is going to be of type int, a plain integer number, no decimal points, and set it to an initial value. Any integer you like between one and 100, but we'll do 37. We also want the total score across all rounds. So score, colon, it's also an int, and the initial score is going to be set to zero. And then finally, we need a var for the current round. Colon, int and the first round, it should be one. Okay, we'll be adding a lot more to this game struct later on, but I think this is a good starting point. So let's integrate this into our app. Switching back to content view dot swift, scroll to the top. And so far we have two properties here. We need one more right now. One to store an instance of a game. This is also going to be a state variable because when the structure changes, for example, maybe the score changes, we want our user interface to update accordingly, so it should be a state variable. We should mark it private like we have the others. It also needs to be a variable, because it can change. Game is what we're going to call this property and it's going to be of type game with a capital G, just like we named the structure we created. And we'll set it to be a new game. So the way we do this is capital G, game, then a pair of parentheses. And this creates a new instance of that template game. All right. So now that we have this, we can update our target label. Right now the target label is hard coded to 89. Instead of showing the hard coded 89, we want to display the target from the game property. To get that, we'll use dot syntax, game.target. But there is an issue now. Game.target is an integer and you can't put an integer inside a text, so we need to convert the integer to a string. You could do this with string interpolation like we did in the alert, but if the only thing we want in the string is this int, there's another way. Type string and inside parentheses, we can put in game.target. And this is making an instance of a string out of that int value. Press command B to make sure that all builds and that builds okay, so I'm gonna hit option command P to make sure the preview's running again. And notice that this used to be 89, but now it's 37, and 37 is the initial value that we set up in our structure, so, so far so good. Remember that every class or struct you create can have data in the form of properties and functionality in the form of methods. We've figured out the three pieces of data we need for bullseye, but what functionality do we need? To start, maybe we can just calculate the points for a given guess. So we could create a method for that called points and have it take a single parameter which is the slider's value. This is the first time we've written our own method in Swift, so let me take a moment to explain the syntax before we dive in. Imagine you want to add a method that has some input. In other words, parameters. And an output, in other words, a return value. To do this, you would simply add a block of code that looks something like this. Basically, you use the keyword, funk, then give your method a name and then you enter an open enclosed parenthesis. Between the parentheses, you put any parameters or input that you want your method to accept. The format for this is the parameter name, a colon, and then the type of the parameter. You can create more than one parameter if you'd like. You would just separate them by commas. After your list of parameters, you put a dash and a greater than sign. This is just two common characters put together, but it has a fancy name, the return token. After the return token, you indicate the type of the object that you'll return as the output of your method like int, double or bool. Inside the curly braces, you put all the code you want to run in the method. When you're ready to return the output value, you enter the keyword, return, and then the value you want to return, like 999 or 9.14 or true. Now, parameters and return values are actually both optional. You can create methods with either or both of them missing. It just depends on what you need. Now that we know what we need, we just need to code it up. So let's switch back to Xcode. And let's add a method to calculate the points in game.swift. So open out the game.swift file again, add a couple of new lines after these properties, but before the closing curly brace. And then to start the method, type in the keyboard, funk, to create a new method, and type in points, which is the name of the method. And in parentheses, we're going to put any parameters that this method takes. In our case, we want to check the slider value to see how close it is to the target value. In this game struct, we already have access to the target, but we don't have the slider value, that's in our view. So add a single parameter and call it slider value. The type we want is an int, so type colon int, and then we put the return token, which is the dash and the greater than sign. And that indicates what type of data does this method return. What do we get back when we call the method? And we're going to return an integer, which is the points that you've earned. After that, you put open and closed curly braces and inside here will be the code that will run when we call this method. For now, we're just going to temporarily return 999 just so we can make sure this works. So now we can switch back to ContentView.swift and let's test out our new method. We want to show users what their score is after they've tapped the hit me button as part of the alert. We're already showing the sliders value in the text here. We can show how many points were earned in the same text. When you have a bunch of texts together, it can get kind of hard to read. So I'll show you how you can format a little easier in Swift. Inside the text put three double quote marks in a row, then start the text you want to show on the next line. I like to put the quotes on their own line because it's easier for me to read, but as long as the actual string starts on it's own line, this will work. Then at the end, close it with another three double quote marks, with those quote marks, again, on their own line underneath the string. Now, if we want a new of text, we can just press return and type you scored xxx points this round. We actually wanted to show the points using our method, so we can call the method right here inside the string, if we use string interpolation again. Do that with a back slash and a pair of parenthesis. Now, inside of the perens, type game to access our game model, and then a dot and then points. And remember that points, it takes a variable or parameter called slider value, and I select that here to pass in the data, put it after the colon. In our case, the data we want to pass in is the end version of the slider value, which we've already calculated and stored in the rounded value variable. And that's it. So this is calling the points method on our game instance, passing in the rounded value. This method will return the number of points which is right now hard coded to 999. So if we try it out in the canvas, just click hit me, and there's our longer alert message saying, you scored 999 points this round, which proves that it's calling our method and returning 999 successfully, and it proves our multi-line string is working.