Hacking with Swift – Challenge 5

I will have to be as concise as possible today (and in the next two days) because I am travelling abroad for a ten-day  and even if I will for sure be able to dedicate my daily hour to Swift I would probably not be able to write and especially publish my report until a bit later (hopefully early next week).

Project 5 was a really funny one and with tons of things to learn. Check Paul’s articles and my report from yesterday if you have not yet read it.

Here is a summary of what we learned:

  • Inserting a single row into a table view is more efficient than calling reloadData(), simply because it adds a single item to the table view whereas reloading the whole table could potentially have to reload thousands of rows in different sections.
  • We can configure the text field in an alert controller if you want to. This was done in the promptForAnswer method.
  • Strings are case-sensitive in Swift.
  • A closure’s capture list comes before its parameters.
    • I knew this to be true but the other option was … well, correct as well? The randomElement() method of collections returns a random element so the option: “Calling randomElement() will always return an random item from an array” makes me raise an eyebrow at least.
  • UITextChecker comes from UIKit and allows us grammar check on words (yes, this got me particularly excited).
  • We can create constants without giving them an initial value (but be sure you do not end your learning to this sentence, understood?!)
  • Index paths store a section and row integer. More precisely an IndexPath is a tuple with a row and section members, both of type Int.
  • An NSRange stores the location and length of something. Using the description in the Documentation: NSRange is “[a] structure used to describe a portion of a series, such as characters in a string or objects in an array.”
  • Objective-C and Swift store strings differently.
  • The firstIndex(of:) method returns nil if the element you’re looking for doesn’t exist.
  • Calling reloadData() will make a table load all its sections and rows from scratch, therefore it should be used only when really needed.
  • Using isEmpty is faster than count == 0.


As we got used to we are tasked with three challenges that will make us write our own code, plus an extra one.

Challenge 1. Disallow answers that are shorter than three letters or are just our start word. For the three-letter check, the easiest thing to do is put a check into isReal() that returns false if the word length is under three letters. For the second part, just compare the start word against their input word and return false if they are the same.

I have followed Paul’s suggestion to go down the easiest route, simply because I am so in a hurry that this is getting stressful. I feel that there should be a better way for solving the first part but well, I will come back to it in the future.

My solution is to add two guard statements (I like them much more than if-else, and find them more elegant), one to isOriginal and one to isReal.

Screen Shot 2019-03-01 at 21.54.42

The app works as intended, just I wish I could change the alert message to show that the word is too short, but maybe for that I should use an extra if-else statement in the submit method which, to me, looks already chaotic enough.

Challenge 2. Refactor all the else statements we just added so that they call a new method called showErrorMessage(). This should accept an error message and a title, and do all the UIAlertController work from there.

Were we talking about “chaotic”? Well, we now have the chance to redeem ourselves.

Here is the showErrorMessage() method:

Screen Shot 2019-03-01 at 22.02.59

The tricky part was just the method’s parameters, but I’m starting to find this kind of writing really funny!

Once the alert controller’s logic is moved inside its own method we can modify the submit method like this:

Screen Shot 2019-03-01 at 22.05.05

We saved a total of 5 lines of codes all counted, which seems little but, should our app grow, would prove crucial. Also, it is not only a matter of saving lines of code, but of making our code read more clearly.

Challenge 3. Add a left bar button item that calls startGame(), so users can restart with a new word whenever they want to.

This for me was a breeze but, really, I have to thank Paul for this because just 10 days ago I was feeling that I could have not written a single line of code on my own. Now my mind just razed to the top of viewDidLoad, added the necessary lines, modified the startGame() method to be @objc so that it would be usable with the #selector keyword and BUM, that was done! I mean, it just works!

Screen Shot 2019-03-01 at 22.10.10

Bonus challenge.

From Paul’s article:

There’s a really subtle bug in our game and I’d like you to try finding and fixing it.

To trigger the bug, look for a three-letter word in your starting word, and enter it with an uppercase letter. Once it appears in the table, try entering it again all lowercase – you’ll see it gets entered. Can you figure out what causes this and how to fix it?

I am not sure if my solution is the right one but I modified the usedWords.insert(answer, at: 0 with usedWords.insert(lowerAnswer, at: 0. This definitely solves the issue but, am I right to assume that our app should consider only lowercase words? Maybe yes because, after all, we created a let lowerAnswer = answer.lowercased() at the beginning so …

I will think more about this tomorrow morning before leaving for the airport!

As usual, you can find the updated GitHub repository here.

If you like what I’m doing here please consider liking this article and sharing it with some of your peers. If you are feeling like being really awesome, please consider making a small donation to support my studies and my writing (please appreciate that I am not using advertisement on my articles).

If you are interested in my music engraving and my publications don’t forget visit my Facebook page and the pages where I publish my scores (Gumroad, SheetMusicPlus, ScoreExchange and on Apple Books).

You can also support me by buying Paul Hudson’s books from this Affiliate Link.

Anyways, thank you so much for reading!

Till the next one!

Published by Michele Galvagno

Professional Musical Scores Designer and Engraver Graduated Classical Musician (cello) and Teacher Tech Enthusiast and Apprentice iOS / macOS Developer Grafico di Partiture Musicali Professionista Musicista classico diplomato (violoncello) ed insegnante Appassionato di tecnologia ed apprendista Sviluppatore iOS / macOS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: