Saturday, May 13, 2017

Recreating Apple's current location dot with Google Maps


A few months ago I was tasked with recreating the stock current location dot from Apple Maps with the Google Maps iOS SDK. At the time, the SDK didn't support animated views on the map. This meant I had to do some hackry where I was placing UIViews on top of the map view, and then synchronising their positions to match the map coordinates of the map view. It was ugly. The main problem with this approach is that there was a delay between the map moving, and the relevant callback to update the dot's position.

Since then Google maps for iOS has come along way. I've noticed that Uber's app doesn't have this delay (for the dot, the cars still lag), so I thought it was worthwhile having another crack at the implementation.


Saturday, January 07, 2017

Travel Report: Ethiopia


Sadly not as many air miles as I would have liked

I spent about 12 days in Ethiopia over the Christmas and New year period of 2016. In a word it was fantastic. I learnt so much about a country that I knew so little about.
The total cost for my trip was £1340 (approximate $1640 USD in Jan '17). This included the direct international return flight on Ethiopian Airlines (on a brand new A350), my 4 domestic flights, all food, all accomodation, everything.

 

Addis Ababa - Metropolitan Africa

 

Merksel Square

There isn't too much to say about Ethiopia's capital. it's about 130 years old, and home to 6 million people. It's has all the amenities that one would expect of a large city, but not much in the way of history. Of course being home to that many people, there are plenty of things to do, just not so many that could be considered uniquely Ethiopian. 

 

Bahir Dar - The closest thing to a beach resort.

 

Lake Tana

Given that Ethiopia is a land locked Bahir Dar is the closest thing that they have to a domestic beach destination. The main tourist attraction is the various monasteries dotted around the lake.

 

Gonder - African Castles

 

One of the ruined castles of Gonder



The highlight of Gonder are the numerous ruined castles that form it's center. The castles are mostly from the mid 16th Century, but vary in age due to the fact that they were built during the reigns of different Emperors.

 

Lailibela - Jeruselam in Africa


The rock hewn churches of this town were the highlight of the trip. The various churches of Lailibela were originally conceived as an alternative to Jeruselam in the 12-13 century. Apparently Ethiopian christians would take a piligramage from Africa to the Holy Land. I have no idea how long that would have taken 1000 years ago, but Google clocks it as 4000km.
Bete Amanuel

Each of the churches is made from a single piece of rock. Most of the churches are surrounded by rock, beneath surface level. UNESCO built roofs over many of the structures in 2008 to protect them from natural erosion, hence the modern looking structures you see in some of the pictures.

Bete Medani Alem, with worshippers for scale
 The cost of entrance was 50USD, and it allowed you to visit all of the churches over a 5 day period. It is important to understand that they are not only huge, but also still used. Pilgrims still travel from around the country every christmas to worship here, many of them walk.



The churches are below ground level and are connected through a series of tunnels and concealed entrances. I explored the churches without a guide, and was able to find most them, without a problem. However the sheer complexity of the entire system will leave you scratching you head as to how it was built to begin with, why it isn't a better known attraction.

 

Harar - The trading hub of Eastern Ethiopia

 

"Bad eyes" gate, one of the original gates of Harar
 Harar is  home to a walled city in the East of the country, between Addis Ababa and the Somali frontier. Unlike the other cities I visited Harar is a predominately muslim city.

A Indian style merchants house
Before the Derg, and troubles of that era the town was prosperous trading outpost host to merchants and Traders from around Middle & Far East. Modern buildings are banned within the city center, and so it's easy to imagine what the city would have been like during it's heyday.

 

Food

 

I often joke that I travel to learn, sleep, and eat. Teff is the main grain of Ethiopia. Wheat flour is available, and eaten by some but for the most part it's all Teff, all the time. The Teff is usually fermented and turned into a "Pancake" called an Injera. Then the Injera is served with everything and anything.

Goran Gorad - Raw meat

I forget the name of this dish, but it's essentially Injera, soaked in butter, served with a mild pepper
This was lovely Soup in Harar, made from a mutton stock, with mutton. The tradition was to tear up the Injera and allow it soak up the soup. possibly the best thing I had in the country.

Gomen Besiga - Which is a Lamb shank, wrapped in a spinich like vetagable.
Another delious meal, I only knew how to read meat, in Amharic so I just pointed at a meat dish and hoped for the best

Conclusion 

Bole, the cosmopolitan heart of Addis Ababa
I had avoided Africa for a long time during my travels, mainly as I didn't want to go on Safari, and I didn't particularly care to see tribes people dancing around mud huts. Ethiopia provided me with the type of travel destination I love; A long and interesting past, good food, nice people, warm weather & cheap amenties. It's not quite Colombia, but it now has a prominent place in my heart.

Thursday, December 08, 2016

Operator overloading in Swift

After years of having to write [@"bar" isEqualToString:@"foo"] I’m delighted that in swift we can simplify things and just write “bar” == “foo”.

However there is an important thing to note. Swift will match the overloaded operator to function that takes the same arguments. Simple.

So if I follow the example set by the equatable protocol, and wanted to compare two NSObject subclasses, I could create a function that looks something like:

And this would work everywhere as expected and print “hello world” …

Well, no. Remember I said exactly the same arguments.

So, If I was to change the optionality of one of the variables:

let a = Object(name: "foo")
var b:Object?

b = Object(name: "foo")

Our custom equality function will no longer be called, as it only expects unwrapped values. This means that the equality would fail, as the pointers do not match, and the test would fail and doSomethingWhenTheStringChanges would never be called.

The solution is fairly simple, you need to create a version of the overridden operator that accepts optionals, but again remember that the compiler is trying to match parameters, so you also need to cover the case where you have one/two unwrapped parameters.

What will now happen, is that when we have unwrapped parameters it will go directly to the first overridden operator, while optionals will use the second. We use the guard to ensure that we can unwrap both, and then do a pointer equality check which will return the correct result if one, or both are nil.

What makes this behaviour particularly “special” is that it will only happen with NSObject subclasses. When using doing the same thing with a pure Swift class, if you are missing the optional variation of the overridden operator the compiler will require you to explicitly unwrap the variable.

Ultimately I think the best way to avoid this mess is to just do things the old fashioned way and override isEqual: in your subclass.

It should also be noted that Xcode correctly syntax highlights the operator depending on whether you will use NSObject’s version of isEqual: or your own at runtime, but there is no warning.

Monday, January 11, 2016

Taking back disk space from Xcode

I have 256 GB SSD in my Macbook Pro, I have no external disks, and no cloud storage other than a Dropbox's free tier. So I think it's fair to say that I'm not a data hoarder. I live my digital life, much like I live my real life, lean and light.

In the last few months I've been constantly hovering around ~8GB of available space, and more recently I've opened my Macbook to messages of "No available disk space". Considering that I dilligently manage my storage I've been a little confused as to why this is the case.

After digging around a little, I discovered that the ~/Library/Developer folder is weighing in at 35.75GB, thats 13% of my disk space!

Digging a little deeper, ~/Library/Developer/Xcode/iOS DeviceSupport/ contains the symbols for every iOS version that you've connected to your machine. If you are like me, and have been doing development for a while, you'll probably have a few, I had 12, going as far back as 7.1.2. They range in size from 600MB, all the way upto 3.36 GB. For my development needs I only need the last two versions; 9.2 & 8.4.1. Removing the unused symbols, as well some dervived data from some old projects helped me recover around 13GB.

If you've installed Xcode Betas you may have had the issue where you have duplicate simulators, sometimes even 3 copies. Each simulator is usually 1GB+ so removing excess ones can save you some additional space. On the advice of this stackoverflow post I installed the snapshot tool, which is part of the fastlane toolkit. It has a handy command called "reset_simulators" which will remove all the simulators, and recreate only the simulators for the current primary SDK you have installed.

The above tips helped me recover 22 GB just from Xcode.


Friday, November 13, 2015

My public key

I'm not quite sure why, but it's taken me a life time to setup encrypted email. Below is my Public key, email away.


Friday, October 24, 2014

Making a numeric/pin pad with NSLayoutConstraints


NSLayoutConstraints are awesome. But like many cocoa technologies (strangely, all the ones that I like) the learning curve is fairly steep.

The goals was simple, I wanted to make a Numeric pin pad that would center itself in it's container view, while ensuring that all the buttons remained square, and aligned .... Ok, maybe not so simple.


Personally I hate resorting to changing the constraint priority, as I feel that most of the time it's a sign that your approaching the problem incorrectly. You can see a gist of the constraints below, ultimately I found the trick was this gem "-(>=1)-". By placing this between the outermost views and then pinning these to the superview, they provide the layout with the flexibility to meet all of it's requirements without having to adjust the superview or simply "explode".

Lastly, if your wondering why i've adopted this strange grouping mechanism inside my loop, I wanted the subview index have a 1-1 mapping with the button number, with out having to resort to setting tags. This way in the button handers I can look up the index of the sender in the subview collection, and know which button it is.

Like 99% of cocoa code, it's not concise. Disfrutarlo!

Monday, July 07, 2014

Future by Design

As a child I loved popular science magazine. Mainly because I was busy designing the future of space propulsion. Hint, it used "controlled" nuclear explosions.

However I've felt that since the 90's we (as a society) have lost our wondering quest for the next generation society. Today I discovered an inventor/futurist named Jacque Fresco. He's been pumping out ideas since before the second world war, some of which I think are brilliant, he also has some interesting views on society, and why it works as it does.