Skip to content

Latest commit

 

History

History
 
 

day-020

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Day 20: Project 2, Part Two

Follow along at https://www.hackingwithswift.com/100/20.

📒 Field Notes

This day covers the second part of Project 2: Guess the Flag in Hacking with Swift.

I have a separate repository where I've been creating projects alongside the material in the book. And you can find Project 2 here. However, this day focused specifically on a number of topics:

  • Presenting random flags to guess
  • Creating an IBAction for flags

Presenting Random Flags

One of the primary challenges we face is figuring out how to choose 3 unique flags at random to present to the user. With our flag choices set as an array, we could use randomElement to pick out a name — but then we still have to make sure each pick is unique. The solution for this is only a bit more intricate: we can first shuffle the array, and then just take the first three elements:

let flagChoices = Array(flagNames.shuffled()[..<3])

And to ensure that our answer has a random position:

let correctFlagChoice = flagChoices.randomElement()

Creating an IBAction for flags

Similar to creating @IBOutlet connections from Interface Builder to code, we can also create @IBAction connections — bindings between interface events and the functions that handle them.

@IBAction func buttonTapped(_ sender: UIButton) {
}

Unlike outlets, however, we don't want a different handle for each button — we want to be able to have the same function handle taps on all of our buttons. Fortunately, Xcode allows us to create connections from several different elements to a single @IBAction handler. In retrospect, of course it would — but it's one of those things that feels delightful the first time you learn about it 🙂.

Anyways, because these functions are called with a sender — the interface element that was the target of the event — we can take advantage of the sender's tag attribute to infer which specific flag was tapped. Here was the original code that I came up with:

@IBAction func buttonTapped(_ sender: UIButton) {
    let flagKeyChosen = flagChoiceKeys[sender.tag]

    if flagKeyChosen == correctFlagKey {
        handleChoice(wasCorrect: true)
    } else {
        handleChoice(wasCorrect: false)
    }
}

Looking back, I have more thoughts about how I'd structure some of the data here, which I'll try to address in the next day's wrap-up. (It's always nice to be able to look back at old code and know better.) For now, though, this covers some important concepts related to interface events and action handling — which Storyboards, divisive though they may be, allow us to connect in some very useful ways 🙌.