Add 1: Creating A Simple iOS Game With Swift in Xcode (Week 2)

Written by: Reinder de Vries, March 8 2015, in Add 1

Updated for Xcode 7.3 and Swift 2.2. Make sure you check the code blocks on this page to get the latest Swift code.

Project Code, Assets and This Series

This code guide is part of a series with 3 parts in total. Check out all 3 parts here:

  1. Add 1: Creating A Simple iOS Game With Swift in Xcode (Week 1)
  2. Add 1: Creating A Simple iOS Game With Swift in Xcode (Week 2)
  3. Add 1: Creating A Simple iOS Game With Swift in Xcode (Week 3)

Download the Xcode project and assets with these links:

Writing the MainViewController code

Alright, let’s do some more coding. Switch to MainViewController.swift. Do you notice the structure of the file?

  • First, there’s an import statement. It tells the compiler to use code from UIKit.
  • Then, there’s a class declaration. It tells the compiler: this is the class we’re creating and we want it to extend UIViewController. When developing apps for iOS, everything you do is object-oriented. All functionality of an app resides in one or more classes. This class called MainViewController holds the code for our interface, and it’s connected to the .xib file. And the class extends UIViewController, which means that we’ll make use of the code Apple wrote for the superclass UIViewController and add our own code to it. Our code, the UIViewController superclass, and the MainViewController.xib file make up the single interface of our app.
  • Inside the squiggly brackets, we write the contents of this class.
  • Then inside the class, there’s methods like viewDidLoad(). This method is called when the MainViewController.xib file is loaded into memory. We use it to set up the view.

Writing the first method: generateRandomNumber()

Let’s create our first method. It’s called generateRandomNumber and it returns a random number of 4 digits, just what we need for our little game!

This is the entire method:

func generateRandomNumber() -> String  
    var result:String = "";

    for _ in 1...4  
        var digit:Int = Int(arc4random_uniform(8) + 1);

        result += "\(digit)";  

    return result;  

And go over it line by line:

  1. First, we write func, and then generateRandomNumber, and then (), and then -> String. We declare our method by writing func, and then set its name to generateRandomNumber. Then, we say that this method has no parameters by writing (). If our method had parameters, we would have written (parameter1:String) for example. Then we set the return value of this method, by writing a single arrow -> and writing the return type String. It means that, whatever may happen, this method must return a String.
  2. Then, we declare and initialize a new variable called result with type String and value "" (empty string).
  3. Then, we write a for-loop. Our loop is supposed to repeat itself 4 times, hence the 1...4. The underscore _ means that we don’t want to keep track of how many times this loop has run, inside the loop.
  4. Then, inside the loops squiggly brackets { and } we write the contents of the loop. We declare and initialize a variable called digit of type Int, that has the value of Int(arc4random_uniform(8) + 1). The function arc4random returns a random value from 0 to 7. That’s 0 or 1 or 2 etc. up to 7 (not 8!). Then, we add 1 to it to always have a value from 1 to 8 (0–7 -> 1–8).
  5. Then, we append the string value of digit to result. Do you notice that result is a String while digit is an Int? We can’t add an integer to a string, that’s why we interpolate the Int inside a string. It’s a quick and dirty way to turn just about anything into a String, by using the "\(...)" notation.
  6. In the end, we return result. Like we declared, the method must always return a String value.

Connecting code with UI: IBOutlet

In order to use the interface elements we created with Interface Builder inside the MainViewController.xib, we must create a connection between the controller class file and the XIB. Such a connection is called an outlet, and the statement to create an outlet goes like this:

@IBOutlet weak var numbersLabel:UILabel?;  
@IBOutlet weak var scoreLabel:UILabel?;  
@IBOutlet weak var inputField:UITextField?;

This is what happens:

  1. First, we start with @IBOutlet this is a special declaration statement that indicates that the property we’re creating is in fact an outlet. A property is just an instance variable (like we created earlier), except that it’s also available for use outside of a class. For now, let’s leave it at that.
  2. Then, we write weak var. That means that this property is weak, as opposed to strong. Weak means that whenever our controller class is removed from memory, the property can be removed at the same time.
  3. Then, we write the property name and type, ex. numbersLabel of type UILabel.
  4. Finally, we indicate that the property is an optional, so it can be nil, written with the question mark ? at the end of the declaration.

Connecting the outlet in Interface Builder

Now, go to MainViewController.xib in Interface Builder. Here’s how you connect the property to the outlet.

  1. Click the first UILabel, the one in the middle of the screen that says “1234”.
  2. Hold the Control-key.
  3. Click-and-drag from File’s Owner (Document Outline, under Placeholders) to the UILabel with “1234”. A blue line should be visible.
  4. Release the mouse when at the label, then a black gizmo should appear.
  5. Select the right outlet: numbersLabel.

Repeat the same step for the score and the textfield. Now you’ve made a connection between the code and the interface, for specific elements and properties.

Watch the video to see how to create the outlets.

Creating 2 more methods: updateScoreLabel() and setRandomNumberLabel()

Switch back to the MainViewController.swift class file and add these two methods, right above the generateRandomNumber method we wrote earlier.

func updateScoreLabel()  
    scoreLabel?.text = "\(score)";  

func setRandomNumberLabel()  
    numbersLabel?.text = generateRandomNumber();  

What do these two methods do?

  1. updateScoreLabel first checks if the property scoreLabel, connected to the outlet for the label with the score, is nil. It’s an optional property, so it could be empty. The code does that with a technique that’s called optional chaining, denoted by the question mark: ?. When scoreLabel is nil, any code behind the question mark isn’t executed! Then, it sets the text property of the label to "Score: \(score)", which is another string interpolation of the score instance variable.
  2. setRandomNumberLabel sets the numbersLabel with a random number, by first checking whether numbersLabel is not nil (using optional chaining) and then setting numbersLabel!.text to the return value of method generateRandomNumber().

Instance variable: keeping the score

Then, create another instance variable just below the outlets you created earlier.

Like this:

var score:Int = 0;

See how this is different from a property or an outlet? It’s just a variable that’s declared in the scope of the class, and not in the scope of a method.

Setting up viewDidLoad()

Now, let’s quickly fill the viewDidLoad method with some code. The viewDidLoad method is overridden with the override statement, just before the func statement. Do you see it? It means that the superclass UIViewController of our class MainViewController has a method with the same name, and we overwrite it with new functionality. Whenever this method is called in the app lifecycle, our method is called, and not the method of the superclass. This allows us to customize the behaviour of the controller and the interface, and hooking into the view lifecycle that the UIViewController has.

This is the code for the method viewDidLoad:



inputField?.addTarget(self, action: #selector(textFieldDidChange(_:)), forControlEvents:UIControlEvents.EditingChanged);

And this is what happens:

  1. First, we call super.viewDidLoad(). This is needed to ensure that the view lifecycle is not interrupted. It’s a call to the viewDidLoad superclass method, and it’s required.
  2. Then, we call setRandomNumberLabel() and updateScoreLabel(). Can you find out what this does? It sets the label in the interface to a random number, and updates the score with the initial value of 0. We set that initial value when declaring the instance variable score, at the top of the class.
  3. Then, we check if optional inputField not is nil using optional chaining. The property inputField is connected to the outlet of the big textfield in the middle of the screen, in our interface. We add a target for an event, that calls an action.

The target, MainViewController, is indicated by self. It’s self-explanatory: self means the currect context, so it means this current class.

The action that’s called is denoted by #selector(textFieldDidChange(_:)). It’s the name of the method that should be called when the event UIControlEvents.EditingChanged happens. We’ll write that method later on.

The event will be fired when the text inside the text field changes, so when you type something in it. For each character you type, it fires an event, and so it executes the method we just gave it.

What happens when we input text?

Take a look at this method, and then add it to your code:

func textFieldDidChange(textField:UITextField)  
    if(inputField?.text?.characters.count < 4)  

    if  let numbers_text    = numbersLabel?.text,  
        let input_text      = inputField?.text,  
        let numbers = Int(numbers_text),  
        let input   = Int(input_text)  
        print("Comparing: \(input_text) minus \(numbers_text) == \(input - numbers)");

        if(input - numbers == 1111)  

            score += 1;  

            score -= 1;  


Can you figure out what happens here?

  1. First, we’re checking if the number of characters in inputField is smaller than 4. When that’s the case, we return the method: execution halts, so the code below return is not executed when the if-statement is true.
  2. Then, we check whether the inputField.text and numbersLabel.text are nil using optional binding with if let, because they’re optionals. Optional binding statements can be combined together with a comma. Each statement is executed consecutively, and when one of them fails (i.e. the variable involved is nil), execution of the if-statement is stopped and the code continues below the end of the statement. Once the text inside the text field is checked, the code attempts to convert these String variables to Int. If that succeeds, the code inside the if-statement (between the squiggly brackets) is executed.
  3. Inside the if-statement, we compare the input value to the random value. Remember the point of our game? You were supposed to add one to each of the digits. Since we don’t include digits 0 and 9, you can easily figure out that the exercise is correct when the difference between the two values numbers and input is 1111.
  4. If the input is correct, up the score one point by writing score += 1, which means “add 1 to score”. If it’s wrong, subtract one point by writing score -= 1.
  5. Then, update the random number with a new value, update the score label, and empty the textfield value.


And there you have it, a running game! Run the app by hitting Command-R and see if you can play it. Encounter any errors? Ask for help in the comments, and backtrace your steps in case you missed something.

Run the app!

Let’s see where this got us. Run the app, and try out the functionality. If you followed closely, your app should do this:

  • Not remove the input code when 4 characters have been entered
  • Still check the code for validity
  • Allow no more than 4 characters

All thanks to delegation! Lets move on and see how we can make this game nicer.

Validation: How Can You Validate Your App Business?

Watch the video to learn a thing or two about validation: the process of determining whether your business is a good one.

See you next time!

Join 11.000+ app developers and marketers
  • Every Monday: get curated app marketing news, resources, tools and goodies in your inbox
  • Grow your app's userbase with the latest App Store Optimization and app marketing strategies
  • FREE: Get the free step-by-step Get Started With Your App Idea guide to set yourself up for App Store success!
Yes, Sign Me Up!

Popular Posts

Written By: Reinder de Vries

Reinder de Vries is an indie app maker who teaches aspiring app developers and marketers how to build their own apps at He has developed 50+ apps and his code is used by millions of users all over the globe. When he’s not coding, he enjoys strong espresso and traveling.

Get instant access to The Step-by-Step Guide: Get Started With Your App Idea

(PLUS: see the tool we use to save a ton on back-end coding)


Comments & Thoughts

  • Marco Sanchez

    Hi I am having trouble in my code and I think that I am missing something. Could someone please look over it?

  • Hey Marco,

    Where do you have that code from? This looks like Swift 1 or 1.2, whereas the current “Add 1” code guide is written in Swift 2. For instance the “count” function is now:

    if(inputField?.text?.characters.count < 4)

    Moreover, you have a squiggly closing bracket "}" too much, right above textFieldDidChange. Also, which version of Xcode are you using? Don't use the beta Xcode 8 / beta Swift 3 just yet.

  • Joci Punk

    Hey, I try to do the outlets, but I do everything like you, and my outlets don’t show up in the XIB. Idea?

  • Joci Punk

    Ok, I solved it. I didn’t change the class.

  • Awesome, well done!

  • Jye Disisto

    when i launch my app.. how come the numbers label doesn’t show up??? Anyone know.


  • Did you add the label to the Interface Builder file? Did you connect the label to an outlet in the Swift file? Are you setting the label.text property in your code?

  • Jye Disisto
  • Jye Disisto


On The Blog