The personal blog of Stuart Breckenridge

Dev Notes - Questions and Answers

As a little side project, I am rebuilding my long forgotten app Amazing Flag Quiz. I don’t have the original source code, so it’s all being done from scratch. My current task is working on the question and answer model. There are few things it needs to do:

  • generate an array of questions (each element a Question) based on the user’s selected continent (e.g. Europe, Africa…)
  • each Question must contain the correct answer and three wrong answers
  • the array of questions and each Question’s answers must be randomised.

Before getting into coding the app properly, I’ve thrown the below together in a playground.

I have an array of all countries:

let allCountries = ["Afghanistan", "Akrotiri", "Albania", "Algeria",...]

My Question class contains a correct answer and three wrong answers, held together in an Array:

final class Question {
    let correctAnswer:String
    var questionOptions = [String]()
    init(cAnswer:String, qOptions:[String]) {
        self.correctAnswer = cAnswer
        self.questionOptions = qOptions

To track which game option the user picks, I’ve created an enum:

public enum GameOptions
    case All, Africa, Americas, Asia, Australasia, Europe, BritishEmpire, USStates

Finally, in order to create a list of questions, I’ve created a protocol with a default implementation:

protocol Questionable
    func questionsForOption(option:GameOptions) -> [Question]
extension Questionable
     Based on option, will generate and return an array of Question objects.
     - parameter option: GameOptions selected by user.
     - returns: [Question]
    func questionsForOption(option:GameOptions) -> [Question]
        switch option
        case .All:
            var allQuestions = [Question]()
            for q in allCountries
                allQuestions.append(Question(cAnswer: q, qOptions: populateOptions(q)))
            // Shuffle 
            return GKRandomSource().arrayByShufflingObjectsInArray(allQuestions) as! [Question]
            /* ... */
            return []
     Populate answers for question.
     - parameter correctAnswer: String
     - returns: [String]
    func populateOptions(correctAnswer:String) -> [String]
        var countrySet = Set<String>()
        // Get four unique random answers
        repeat {
            let i = GKRandomDistribution(lowestValue: 0, highestValue: allCountries.count - 1).nextIntWithUpperBound(allCountries.count - 1)
        } while countrySet.count < 4
        // Add answers to an array
        var options = [String]()
        for c in countrySet{
        // Shuffle answers
        return GKRandomSource().arrayByShufflingObjectsInArray(options) as! [String]

In terms of usage, I need to generate questions and answers when my GameViewController appears on screen, as part of viewDidLoad, as shown below:

class GameViewController:UIViewController, Questionable {
    var list = [Question]()
    /* ... */
    override func viewDidLoad() {
        list = questionsForOption(.All)

I’m satisfied with this solution: it’s less than 100 lines of code and is easy to follow.

I seem to remember this being much harder when I wrote Amazing Flag Quiz originally and I’m mindful of what Henri Cartier-Bresson once said:

Your first 10,000 photographs are your worst.

That applies to your first 10,000 lines of code as well.

Next up: presentation logic.

Parse to Close  

Kevin Lacker:

We have a difficult announcement to make. Beginning today we’re winding down the Parse service, and Parse will be fully retired after a year-long period ending on January 28, 2017. We’re proud that we’ve been able to help so many of you build great mobile apps, but we need to focus our resources elsewhere.

We understand that this won’t be an easy transition, and we’re working hard to make this process as easy as possible. We are committed to maintaining the backend service during the sunset period, and are providing several tools to help migrate applications to other services.

While Parse will be releasing a migration tool to assist with moving existing data to any other MongoDB database, the fact that it is closing will come as a huge blow to developers who make use of the platform.

New DeLoreans Coming Soon  

Jordan Golson:

The DeLorean Motor Company, which acquired what was left of the original manufacturer 30 years ago, currently focuses on repairing and restoring all the DeLorean vehicles that are floating around the world. But now, with this specialty legislation, the company can use its millions of factory parts (and some that have been recreated from the original blueprints) to build new, 2017 model year DeLoreans complete with a crate engine from an outside supplier. Pricing is expected to run between $80,000 and $100,000.

I wonder how much the certificate of entitlement would be for a DeLorean in Singapore?

Twitter Stops Serving Ads to VIPs  

Peter Kafka:

Twitter makes its money by showing ads to its users.

But not all of its users: For the past few months, the social media company has stopped displaying ads, or has dramatically reduced the number of ads it displays, to a small group of some of its most prominent and active users.

For those people, Twitter is an ad-free, or nearly ad-free, experience.

Advertisers must be curious about this move. They are paying for their ad to reach customers and Twitter is arbitrarily taking that opportunity away from them based on the particular user’s valuableness?

Twitter sources say the company doesn’t select the no-ad or low-ad group purely by star power, but by a variety of criteria, including the volume and reach of the tweets they generate.

Fortuitously, for the rest of the us, there’s a solution to obtaining an ad-free Twitter experience: use a third party Twitter app. I recommend Tweetbot 4.

Note: I have previously experimented with Twitter ads in the past and discovered they are very good at enshittening a user's timeline while not being very useful.

The Best Email App for iPhone  

Sean O’Kane via The Verge:

More than anything, a good email app should be fast. Refreshing your inbox, loading messages — none of these things should take more than a second or two. It should also give you plenty of different ways to deal with the daily email deluge. That means letting you do things like reply, archive, delete, or schedule messages with swipes or taps, while also giving you easy access to other services like calendars and files.

Beside powerful options, a good email app should also have a great design — not just so that it’s easy on the eyes, but so it’s easy to use. If an app makes it too hard to glance at your inbox and know what’s important, it’s time to try a different email client.

It seems strange to me that the review fails to consider a vitally important part of email: Security. No third party mail app supports S/MIME which has been baked into iOS since 2011. I accept that email security is unwieldy and causes issues with webmail, but third party apps should, at the very least, support S/MIME.

Apple Watch Screensaver for OS X  

Beautiful work by Rasmus Nielsen to bring Apple Watch faces to OS X as screensavers.

Bringing the best part of your new shiny watch to OSX. We’ve created this OSX screensaver just for funs sake.

Apple Watch Screensaver features 5 watchface variations. Chronograph, X-LARGE, Simple, Normal & Utility.

With 80 different variations of watchfaces there is ton a possiblities for individualty and fun and simply no room to be boring.

She Scullys Herself  

Tonight, The X-Files returns to TV for the first time since 2002. If you need a fix before then, you should have a listen to episode 284 of The Incomparable1:

Just as “The X-Files” is revived for a limited-run miniseries, we take time to look back at this classic TV series from the 90s. (With gorgeous new HDTV versions available on Netflix!) We discuss some classic episodes, the dynamic between Scully and Mulder that really made the show work, and a whole lot more. The truth is in here—you just have to want to believe.

Playing Ping Pong with Water in Space  

Before watching the video, Eric Berger, for Ars Technica, helpfully points out:

But in space the water molecules at the surface are bonded such that the tension holds them together as spheres, and water can be bounced back and forth, like a ball.

It’s so very strange seeing water behave this way.

10,000 Steps  

I’ve been taking part in the Global Corporate Challenge for the last three years, slogging away at achieving more than 10,000 steps per day1. To read that it’s all a bit pointless is disheartening to say the least.

Geoffrey A. Fowler, for the Wall Street Journal:

What’s so bad about the old 10,000 step rule? Anything that gets sedentary people moving is a good thing, doctors say. The 10,000 figure originated with a 1960s Japanese step-counter marketing campaign, a time and place that may not have much relevance to 2016 bodies hunched over computers with a bag of Cheetos.

Step counters ignore the imperative to raise your heart rate, which the American Heart Association says is key to stemming our No. 1 killer, heart disease. Regular walking isn’t very strenuous, unless you go uphill. And basic step counters also don’t give you hard-earned credit for benching 150 pounds or completing a spin class.

  1. This is a much harder task in a tropical climate. ↩︎