A day in Seoul

When people ask me “what do you like the most about living in Hong Kong?” I always reply the same: the geographical location. Every destination in Asia is within reach of a 5 hours long flight.

So, this weekend, after 11 years of living in Hong Kong, this weekend we finally crossed Seoul off the Travel List.

We spent only one full day in the city, and we only visited Gyeongbokgung, the Royal Palace, and the Bukchon Hanok Village 

Being the mid-autumn festival, there was plenty of people dressing traditional, which made for some good photos.

Selfie time!
The Royal Palace. Every  country has its own Versaille.
Royal Palace Gardens

There were a couple of things that caught our attention. First, the gas masks in the metro stations:

And, as expected, the ubiquitous wi-fi. Like in this metro car:

🤔

In today’s episode of I don’t understand the economics of global trade, I present you a box of the most British tea ever.

So far so good.

Now let’s take a look at how this box of the most British tea ever made it’s way to Hong Kong (which, by the way, happened to be a British colony not that long ago)

So, the box of the most British tea ever was imported from Britain to the US, and then from the US to Hong Kong.

As I said: 🤔

Stuff I’ve read between August 5th and 12th 2018

As a follow up to the “I’m out of Twitter” post, I am starting a weekly recap of what I’ve read.

Stuff from the internets

There’s a limit to the amount of knowledge a single person can cram into their head in a lifetime

When knowledge is the limiting factor

Sunshine, sensuality, and a dash of danger… the ‘warm south’ has fascinated writers and artists for hundreds of years. But why are the Brits so obsessed?

From EM Forster to Mamma Mia! Why we can’t resist the Mediterranean

… You have created all these classes and complexity to replace only one line of code, which is unlikely to be changed.

Dependency Injection smells

We’re not used to thinking about the tech industry in terms of labor […] But tech, like any industry, is composed of workers and owners. The labor of the former generates profits for the latter

Can Silicon Valley workers rein in big tech from within?

From vaccines to climate change to genocide, a new age of denialism is upon us

Denialism: what drives people to reject the truth

Books

Finished
Greeks Bearing Gifts

Started
The Male Factor

So long, twitter.

I am aware that nobody really cares about it, but I just deleted all my tweets.

Actually, there is one person that cares: me. And that’s precisely why I have deleted them.

I have had an on/off relationship with twitter for a long time. I am not sure when I signed on to the service for the first time, but I still lived in Madrid, so that would be at least 11 years ago. In these 11 years I think I have deleted and reactivated my account at least twice.

This time it is different though.

This summer I have jumped into the iOS beta track extremely early, and on all my devices, including my phone.

One of the new features of iOS 12 is something called “Screen Time”, which provides a very interesting view of the way you use your devices.

I had never realised how much time I have been wasting on twitter every day until I saw the charts in front of me. It was more that two hours per day!

So I decided to set a time limit for my twitter client (1 minute a day) and to remove the app from my home screen burying it in a folder.

It’s been a week since I did that, and this morning I noticed that I wouldn’t have even needed to set a time limit. I have not launched the app in more than a week!

That has given me an opportunity to realise that:

  1. I am a bit more clam. I am perfectly aware that the world has turned into a place where racism and plain old fascism are rampant, enabled and promoted by some governments and most of the media, but I don’t need to be constantly reminded of it, for hours, every day.
  2. Twitter is guilty of that spread as well. They keep justifying giving a voice to those spreading hate speech. I don’t want to be a part of that.
  3. I read books again. I have the privilege of deciding my own work hours, so I have the privilege of being able to set aside some time, every day, where I have nothing to do. Now I can spend that time reading.
  4. I haven’t written anything in this blog in ages. I miss writing, even if there is nobody reading.

Twitter and flickr were the only two social platforms, that I’ve ever participated in, actively. I still miss flickr, I don’t think I’ll miss twitter.

TIL: Swift 4 and protocol composition.

One of the things I like most about Swift is that almost every day I learn something new, more often than not, something new that makes me write more readable and cleaner code.

Today I realised that protocol composition, which I kind of knew could be used to compose a SuperClass and a Protocol, can help remove some downcasts at runtime, and substitute those downcasts by the compiler yelling at you when writing the code.

Let’s take this code. As usual, it is difficult for me to come up with a relevant example that illustrates what I want, but is also simple enough to be understood without too much context.

Notice how I have to check, at runtime, that the parameter I pass to deliverPresentation implements the Presentable protocol.

If we rewrite the Presenter to be like this, we can make the compiler enforce that whatever we pass to deliverPresentation as a parameter also implements Presentable, so we can avoid the downcast.

A real life example? From this:

To this:

 

Why code comments and documentation are better than being an arrogant jerk who keeps other developers out

For months, I have been playing around, in my head, with the idea of a post about documentation, and how it just should be one of the things that every software engineer does regularly.

I have written a few drafts, I have listed arguments both for and against writing documentation, I have debated and tried to debunk some of the usual arguments against it, and in the end, it all comes to the following:

Writing some documentation is better than being an arrogant jerk who keeps others out.

Period.

Building boundaries with third party libraries

The joys of jet lag. Here I am, at 2:43 am, trying to finalize a post that I started writing a couple days ago, while flying over the Pacific Ocean.

This is about dependencies, those third party libraries that often provide out of the box solutions to complex problems we need to solve.

Importing a third party library will save time and effort. Just add a line to a pod or Carthage file, and boom! We have saved days, weeks or months of development.

There are multiple benefits in relying on a third party library. Popular libraries are often well tested, and contain the knowledge of many developers about a given problem. Third party libraries save development time. Third party libraries avoid reinventing the wheel.

But third party libraries are code that you have not written, code that you don’t actually own, but that you somehow have to start maintaining as soon as you import it into your codebase.

Let’s take an example. Loading images, asynchronously, without blocking the main thread, in a table or collection view cell is a complex problem. We need to cancel image downloads when cells are not visible anymore, we might need to handle cell reusability, and ideally we should cache images. None of those problems are trivial to solve, and might require time and finesse to get right.

On he other hand, we could just import a third party library, like, for example, Kingfisher.

All we’d need to do would be adding a line to a pod / carthage file.

But…

We have created a subtle problem here: our cell’s code depends on Kingfisher. We need to call a specific method in that library, passing a set of specific parameters, in the way that library expects.

That be not be a problem if we only have one cell. But things start getting dangerous as soon as we have more than one cell.

Let’s say there are 10 different cells that present images in our codebase. Kingfisher is so convenient that we will repeat the same code in the 10 of them.

What would happen if, for some reason, Kingfisher stops being maintained? Or a new version of Swift breaks source compatibility again, and this library does no get updated? Or a new library comes by, that is twice as efficient as Kingfisher.

Then we would have a bit of a problem. Our code is strongly coupled with the specific api of a very specific library, and updating our code to use a different library might require getting into shotgun surgery mode.

Shotgun surgery.

How do we switch? Well, we could just do a search and replace, or search all the calls to Kingfisher and update them to use the new, hottest library.

But that is not very efficient, obviously.

So how do we avoid the problem?

Building boundaries

The same way that we have tools and mechanism to decouple some parts of our code from some other parts of our code, we have tools and mechanisms to decouple or code from third party libraries.

And the best tool for decoupling things is, as usual, a layer of indirection.

In this case, we could add a layer of indirection by encapsulating the call to the third party library in an extension to UIImageView. This extension would be code under our control, and will contain a single point of dependency with the third party library.

Our cells will load images by calling a method that belongs in our side of the codebase, not in the library’s side of it.

Now if we want, for whatever reason, to switch to a third party library, all we have to do is modify the implementation of our extension. Import a different library, update the presentImage method to that third party library’s API, and we are good to go.

Final words

Introducing seams between our code and third party libraries decouples our code from external dependencies. That way, we are free to modify those dependencies without having a big impact in our codebase.

PS

Kingfisher is a great library that solves a complex problem in an elegant way. I strongly recommend considering it.

TIL: CoreSimulator logs

Adding an Intent Extension to an existing WatchKit app, and trying to run the project in the simulator immediately after will not work, at least on the latest Xcode9 beta.

The error message does not look very helpful:

Somehow I recalled reading a few days ago that the simulator logs to ~/Library/Logs/CoreSimulator/CoreSimulator.log

So I checked the logs in Console, and I found this:

And there is the actual reason. A Siri Intent extension without actual intents is preventing the app from installing in the simulator.