Hacking with Swift – Challenge 19

As a continuation for Day 74 I will be reviewing what was taught in Project 19 and face the three challenges. This project was interesting but definitely something I will not get back to for a good while, personally.

Well, I just listened to the video for this day of challenges and I feel like… what the heck? … what are scripts? Which scripts did we use in this project? I only found this: alert(document.title);. Is that it? What else should we use? I mean… again… that feeling of being stuck like an idiot…


  1. You must ship an app if you want to ship an extension (we are reminded that extensions are shipped inside the parent app). I am using a great extension as of late called Stop the Madness that helps user regain control of their browser. It is amazing, check it out!
  2. Every iOS app has an Info.plist file. This contains informations that are fixed in place like the language used in the app, the app version itself. To be thorough, every app I have seen so far — even not iOS — has an Info.plist file so it seems to be something quite important.
  3. NSDictionary is an Objective-C dictionary. I am increasingly fascinated by how the core of iOS (and especially macOS) is working, can’t wait to learn about it more. I said “learn”, not being challenged! 🙂
  4. When our Swift extension finishes we can send values back to JavaScript. This time I answered wrong, I chose the other option but it seems that contentInset doesn’t exist as a property for UIViewController. Bah… again, I want to be questioned about what I had to learn, not about what I had no chance to ever learn… It seems a good thing that I started to publish my articles, they would have been too full of crazy swears otherwise.
  5. When loadItem(forTypeIdentifier:) completes it will call a closure so we can act on its data. New question, new mistake. I really thought that connecting a hardware keyboard would not have any impact on the onscreen keyboard. But, speaking seriously, for goodness’ sake, when on Earth did one ever attach a hardware keyboard to an iPhone?. I may understand doing that for the iPad but still, I would find it very difficult to do. What is intended for “hardware keyboard”? Why do we have to figure out everything by ourselves? Why do I have to get so angry every time?
  6. If a device has a home indicator at the bottom rather than a home button, we need to adjust its keyboard frame. This is needed for the latest devices without a Home button, such as the iPhone XS. We need to adjust our keyboard calculation by the safe area’s bottom value.
  7. The keyboard frame can change many times while our app is running. As an extra comment we are getting “The user can hide and show the QuickType bar as often as they want”. What the heck is the QuickType bar? Where did we learn about it? Where was it taught? Again, please, everyone, stop asking for or speaking of things that you didn’t explain! Stop right now! … After looking for it and, yes, again, losing a considerable amount of time, I got to realise that the QuickType bar is that triptych bar where you get typing suggestions. Nice… WHY DIDN’T YOU TELL US ABOUT THAT? … Please, always explain things to people as if they were complete ignorants, you never know who will come and listen to your videos or read your books. Or, just mark the material “PRO” as the “Pro Swift” book. I am sure it has many less sales that “Hacking with Swift” but at least it doesn’t try to fool you into thinking that this doesn’t require a very, very good base!
  8. The addObserver() method of NotificationCenter lets us watch for a particular notification. Fine, I was awake during that part of the class when the word “keyboard” was repeated at least 2.000 times! In summary, this method lets us attach some code to run when a notification comes in.
  9. NSValue exists because Objective-C couldn’t put values like CGRect into arrays and dictionaries. Again, I am very interested in learning more and more about this. I believe in all-round knowledge while now we have a few tastes and bits of a thousand subjects without feeling sure about anything. We are not trying to build a pyramid were every single brick is important, we are instead putting the first stone of twenty different buildings and I am really struggling to see some progress in all this.
  10. The contentInset property of a UITextView determines how text is placed inside the view. Well, after having badly mistaken the first question, it is nice to see that I have been able to make this right!
  11. Our own preprocessing JavaScript runs before our Swift code. I have really been too short of a time inside this to understand what all this means and I am not really being enthusiast about it.
  12. Action extensions appear inside Safari’s UI. Well, yes they do? Just I would really like to get more explanations, more details, just … more.


Challenge 1: add a bar button item that lets users select from a handful of prewritten example scripts, shown using a UIAlertController—at the very least your list should include the example we used in this project.

When I first read this I got my usual panic rush, but then I just tried and it worked. Nice!

First, in viewDidLoad, add a .leftBarButtonItem navigation item with a title of “Scripts”, a plain style, a target of self and an action of #selector(chooseScript).

Second, write an @objc method called chooseScript that accepts no parameter and returns nothing. Inside, declare a new alert controller with a title of “Choose a script”, no message and a .alert preferred style.

Third, add three actions, each one very similar to each other but with different titles and handlers:

  1. Title: “Document Title”, handler: self.script.text = "alert(document.title)"
  2. Title: “Page Links”, handler:
self.script.text = """
	var links = document.getElementsByTagName("a");
	alert("There are " + links.length + " links on this page.");

Thanks to Kirsty Darbyshire for this. I didn’t find her Twitter handler or any other web presence of her but she was very helpful in this.

  1. Title: “Forza Juve”, handler: self.script.text = #"alert("Forza Juve!";"#

I don’t know if I used the new Swift Strings correctly here, I should go and study them but, using the # symbol, I could avoid double escaping the quotes!

Challenge completed! Code here, branch “challenge19-1”.

Challenge 2: you’re already receiving the URL of the site the user is on, so use UserDefaults to save the user’s JavaScript for each site. You should convert the URL to a URL object in order to use its host property.

I’m not really understanding what is going on here… are you?

I think I managed to convert the String url to a URL object but… why should I use the host property? I am not understanding this at all so I am just trying it.

I tried to go to the GitHub repository for the 100 Days of Swift and copied from the only proposed solution. Well, I do not know what should happen because, once more, we are left alone in the dark, but whatever should happen nothing happens for me.

I mean … what can I do to solve this?

I wrote a save method, called it after the pageURL was set, then wrote a decode call at the end of viewDidLoad but… nothing, nothing gets loaded at all, or maybe it does but I have no way to know.

If I think more about that I should try to save the JavaScript data but, where is that? Is it the script.text? But how can I save it?

I even opened the only provided solution and even that one doesn’t work! Come on!

Challenge 3: for something bigger, let users name their scripts, then select one to load using a UITableView.

I will not even attempt this one, I am really fed up.

Challenges should stretch us, not destroy us.

This way of doing is really killing my resolve.

I have come here to learn, not to be constantly humiliated!

There is no extra code for this project. I have not managed to do anything more on this and I really doubt I will ever try to do something more, and this is more in protest against the way we are being taught. This is just outrageous!

I even asked personally for help to Paul (who, by the way, always says on the website: “are you stuck? Contact me!”) and didn’t ask him to look at my code—I know that is too much work—, I simply asked to provide an official best solution from his side as we do not have any mean to understand what is going on if we already do not know, and he answered:

I am rather busy and not currently in a position where I can drop things to solve problems.

Fine! Then explain me this, which is there in every page of the initiative!

So, I either do not understand the meaning of “need help” or the problem is indeed somewhere else.

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: