Russian Space Station
The musing and sometimes not so wise words of Jonathan Dalrymple, Global Traveller, Programmer, Financial Rocket Scientist, Conspiracy Theorist, Part-time comedian, full-time funny man and whatever else i randomly decide to do.
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.
Labels:
apple,
Development,
google,
google maps sdk,
ios,
Programming,
swift
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.
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.
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
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 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 |
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 |
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:
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.
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.
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.
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.
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.
Subscribe to:
Posts (Atom)