tag:blogger.com,1999:blog-125392002024-03-07T04:54:07.216+00:00Russian Space StationThe 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.Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.comBlogger429125tag:blogger.com,1999:blog-12539200.post-45199614400462043242017-05-13T17:45:00.001+01:002017-05-13T17:45:16.883+01:00Recreating Apple's current location dot with Google Maps<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUqsyO3IolLfwTVr0-Y4PR9WTBDfkDkZtkutncExhrya2qZQHjeO_E5uAv-GhAsqIeLh7ir8IbxEoviOv2SDQFhnd_BbtUS8WHwnKsvwiTTD8LN5z4gluxZA4SAThiDoEBzxKs/s1600/currentLocation.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUqsyO3IolLfwTVr0-Y4PR9WTBDfkDkZtkutncExhrya2qZQHjeO_E5uAv-GhAsqIeLh7ir8IbxEoviOv2SDQFhnd_BbtUS8WHwnKsvwiTTD8LN5z4gluxZA4SAThiDoEBzxKs/s320/currentLocation.gif" width="170" /></a></div>
<br />
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.<br />
<br />
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.<br />
<br />
<br />
<script src="https://gist.github.com/veritech/b7947c2bde96c4538422bfcd9ab4a729.js"></script>Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-46661879630833816702017-01-07T15:29:00.004+00:002017-01-07T15:34:57.893+00:00Travel Report: Ethiopia<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div id="map_div">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTRBxY87BuzBau1wBXQJUApMucRmEXa0rePiUgK0plE6l-RuBZrARZg5W25vTItwg92lWaehy0NVpE4d8y0GGz9FojjPgg2rTdy4phjm8_xPl1Klrvt9ZBFwqMvfxh0ZfmrZ38/s1600/map.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTRBxY87BuzBau1wBXQJUApMucRmEXa0rePiUgK0plE6l-RuBZrARZg5W25vTItwg92lWaehy0NVpE4d8y0GGz9FojjPgg2rTdy4phjm8_xPl1Klrvt9ZBFwqMvfxh0ZfmrZ38/s640/map.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sadly not as many air miles as I would have liked</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div id="map_div">
<br />
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. </div>
<div id="map_div">
</div>
<div id="map_div">
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. <br />
<h3>
</h3>
<h3>
Addis Ababa - Metropolitan Africa</h3>
<h3>
</h3>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-yppjBwqGYNcEc-NhdaISfDWBaRD1qP_TMs9qJWg9A3-9NB9gA7SwFqNXt1X-Y4Sx-C_lbnpnEJWsO0ile_OZe1vrbWvEUjBFFphu5aY9iBa7-zXILz39R88hJEyc-OwKYS8L/s1600/IMG_4279.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-yppjBwqGYNcEc-NhdaISfDWBaRD1qP_TMs9qJWg9A3-9NB9gA7SwFqNXt1X-Y4Sx-C_lbnpnEJWsO0ile_OZe1vrbWvEUjBFFphu5aY9iBa7-zXILz39R88hJEyc-OwKYS8L/s640/IMG_4279.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Merksel Square</td></tr>
</tbody></table>
<br />
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. <br />
<h3>
</h3>
<h3>
Bahir Dar - The closest thing to a beach resort.</h3>
<h3>
</h3>
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLV6EbQ5g_UozHzHiYH7AJc862-wZA58vo3wfCTGMIgYC1dByO3q623-BMZSej_-gPcsUe7TUcdTZs1bZRs45Fi2BNJ11icYEzkmd8WbQ-_c4t771F0PB0CRsCKeMKOfEi0UIX/s1600/IMG_4298.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLV6EbQ5g_UozHzHiYH7AJc862-wZA58vo3wfCTGMIgYC1dByO3q623-BMZSej_-gPcsUe7TUcdTZs1bZRs45Fi2BNJ11icYEzkmd8WbQ-_c4t771F0PB0CRsCKeMKOfEi0UIX/s640/IMG_4298.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Lake Tana</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
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. </div>
<h3 class="separator" style="clear: both; text-align: left;">
</h3>
<h3 class="separator" style="clear: both; text-align: left;">
Gonder - African Castles</h3>
<h3 class="separator" style="clear: both; text-align: left;">
</h3>
<div id="map_div">
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0DEsn6ykXr4hyEWGkM_suf8UhfKksEXys5W6c7a5IcZYGWMYZ69w9xeei0l8wnXqaUT3uoXOxHgYkTo5idj0yHfejieTsxSQICEYwU-p0uuWR641Yp4aLcVrkmoDz1WkzNjFD/s1600/IMG_4322.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0DEsn6ykXr4hyEWGkM_suf8UhfKksEXys5W6c7a5IcZYGWMYZ69w9xeei0l8wnXqaUT3uoXOxHgYkTo5idj0yHfejieTsxSQICEYwU-p0uuWR641Yp4aLcVrkmoDz1WkzNjFD/s640/IMG_4322.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">One of the ruined castles of Gonder</td></tr>
</tbody></table>
<br /></div>
<div id="map_div">
<br />
<br />
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.<br />
<h3>
</h3>
<h3>
Lailibela - Jeruselam in Africa</h3>
<br />
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.</div>
<div id="map_div">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><img border="0" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIQTr6N4Y9M2fuOD7UT6JuYFolDdpbHA2RPGVZeG-gh_ko04x7kvNE74zZ8ggY8_2d0Bvo_321qhQmrk7WlNVJfkjnTIiDHRMRmSnVNJqmyHDgqpMwWtOu42bfrCdwYHocaaFT/s640/IMG_4837.JPG" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bete Amanuel</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMRmzstlJkDqPXZxoBckm1qyeXB_q-nH46-5UZueRELI0_sZpEP6ACBAxY410LrMgTlkjojhjLbdaz6T2wQ0o5WkqQ0Ncp-Xg09UTGcXELxoBdF8kLs_0aTjb-IjP-LeokeFhS/s1600/IMG_4394.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMRmzstlJkDqPXZxoBckm1qyeXB_q-nH46-5UZueRELI0_sZpEP6ACBAxY410LrMgTlkjojhjLbdaz6T2wQ0o5WkqQ0Ncp-Xg09UTGcXELxoBdF8kLs_0aTjb-IjP-LeokeFhS/s640/IMG_4394.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bete Medani Alem, with worshippers for scale</td></tr>
</tbody></table>
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.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEMSasPqAwikyEAkxJUJBDECGL_1ky8hsjAm0KNAxqaWZeGzYCwFGypXfX3EE4BxQ-ZiiF3B63NwOR7BuDZZTtI4GquEdIsSThJGR_WyfJQ7YrbHs8ax6qYSa7eh6c6IOoruJR/s1600/IMG_4413.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEMSasPqAwikyEAkxJUJBDECGL_1ky8hsjAm0KNAxqaWZeGzYCwFGypXfX3EE4BxQ-ZiiF3B63NwOR7BuDZZTtI4GquEdIsSThJGR_WyfJQ7YrbHs8ax6qYSa7eh6c6IOoruJR/s640/IMG_4413.JPG" width="640" /></a></div>
<br />
The churches are below ground level and are connected through a series of tunnels and <span data-dobid="hdw">concealed</span> 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.<br />
<div id="map_div">
<h3>
</h3>
<h3>
Harar - The trading hub of Eastern Ethiopia</h3>
<h3>
</h3>
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-jd7znpRo0bWofqao9oW-SoW1OPxj4RKDOUFM_i0-c4_zQtrZUEQs92bwpbVXnC7B6isxori8lDr09SqV66i9o017Kq13Xn5G_nBCxyBVTCYpLc-YacqXfHtrgY3s4jtTFa83/s1600/IMG_4907.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-jd7znpRo0bWofqao9oW-SoW1OPxj4RKDOUFM_i0-c4_zQtrZUEQs92bwpbVXnC7B6isxori8lDr09SqV66i9o017Kq13Xn5G_nBCxyBVTCYpLc-YacqXfHtrgY3s4jtTFa83/s640/IMG_4907.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">"Bad eyes" gate, one of the original gates of Harar</td></tr>
</tbody></table>
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. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP43LKaMY1wOXfvLGIb-YZa_kZ2qyJvsz_3ZvoQW5UVOmOMwZr1uNXTX-vCKmeoPqf7Ta8Cs8Q6iVTNn0Mx-0w5kD3wUpXfc2QFWrdBFbe8Z0hGwPi-4FJVh12K7f97BzxnZSc/s1600/IMG_4909.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP43LKaMY1wOXfvLGIb-YZa_kZ2qyJvsz_3ZvoQW5UVOmOMwZr1uNXTX-vCKmeoPqf7Ta8Cs8Q6iVTNn0Mx-0w5kD3wUpXfc2QFWrdBFbe8Z0hGwPi-4FJVh12K7f97BzxnZSc/s640/IMG_4909.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A Indian style merchants house</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div id="map_div">
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.</div>
<div id="map_div">
<h3>
</h3>
<h3>
Food</h3>
<h3>
</h3>
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.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzJzrW7x11kmJVgE7DXJf18EuwwIEyuuLw-P5nKmRx4T5LsfJfjRgaARQlPvi-KqD3E-tx_6eZ0QTcZHNWGAXJehc5x78yHDsfr8MZFHrE6AXERByuqcI66prtbbEOlXjH3xHp/s1600/IMG_4314.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzJzrW7x11kmJVgE7DXJf18EuwwIEyuuLw-P5nKmRx4T5LsfJfjRgaARQlPvi-KqD3E-tx_6eZ0QTcZHNWGAXJehc5x78yHDsfr8MZFHrE6AXERByuqcI66prtbbEOlXjH3xHp/s640/IMG_4314.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Goran Gorad - Raw meat</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgPffTW10UzDVXt1Fyxjc2nI-oW82VdTFizTrt1vMvKBRB6YVk9WiX6wxO4GJu46V_gSODeKuAcqHYeSUY0mZQHkW9S0DvSxVbD125zcJpKfvbKp_BOvAXBJHipyxAyx9BR8GU/s1600/IMG_4390.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgPffTW10UzDVXt1Fyxjc2nI-oW82VdTFizTrt1vMvKBRB6YVk9WiX6wxO4GJu46V_gSODeKuAcqHYeSUY0mZQHkW9S0DvSxVbD125zcJpKfvbKp_BOvAXBJHipyxAyx9BR8GU/s640/IMG_4390.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">I forget the name of this dish, but it's essentially Injera, soaked in butter, served with a mild pepper</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEito8vgf01hkpCxg4nRRyB-wOMeHfk4vntJEW-4XmCz38SaneineLI1qI99x_W3dKuA7d2cfR5WX4bXeNBaLQ-0RgDSj3tOBnlkj6YnMt48y-q-Fsbg08CqQAT21N_h4bKQ8_er/s1600/IMG_4913.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEito8vgf01hkpCxg4nRRyB-wOMeHfk4vntJEW-4XmCz38SaneineLI1qI99x_W3dKuA7d2cfR5WX4bXeNBaLQ-0RgDSj3tOBnlkj6YnMt48y-q-Fsbg08CqQAT21N_h4bKQ8_er/s640/IMG_4913.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">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.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3U1JflEYtU2gto22SL5W4jyKyuqOTanDN_cdZLnoie-50TKsA_6b4CFbpxgrFgeDWX8hsZ5a0mzSwkiXS99wO-1CcJNX0WqoVaiXD-cxnmy2KO2X7Ba2pgWMBVCeboih2cx_8/s1600/IMG_4928.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3U1JflEYtU2gto22SL5W4jyKyuqOTanDN_cdZLnoie-50TKsA_6b4CFbpxgrFgeDWX8hsZ5a0mzSwkiXS99wO-1CcJNX0WqoVaiXD-cxnmy2KO2X7Ba2pgWMBVCeboih2cx_8/s640/IMG_4928.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Gomen Besiga - Which is a Lamb shank, wrapped in a spinich like vetagable. </td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6rv0Es0KxEC4YiugTN7OBrVMakDUjygk5IU35SjVDbDf5ioPXmESR3zYQwGT6Nt8vx4xfYsYnwKxuCcDJ3HhmFSfWqewz3lhmjQU7uMtUKjpJqSBQIjEpG-Ec2w5t4GtWHBTT/s1600/IMG_6984.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6rv0Es0KxEC4YiugTN7OBrVMakDUjygk5IU35SjVDbDf5ioPXmESR3zYQwGT6Nt8vx4xfYsYnwKxuCcDJ3HhmFSfWqewz3lhmjQU7uMtUKjpJqSBQIjEpG-Ec2w5t4GtWHBTT/s640/IMG_6984.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">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</td></tr>
</tbody></table>
<h3>
Conclusion </h3>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisCe_XzmlWn-hMcYayZnKToaTxP5aJnzKRocfdLtVKt4C-tfsT7BOIxZrBYneS2FIJhViSpxH0HaFPLENRb2fxBNnYkOqgc4JhJXv_biG5mGXTV8HI5bwC-mXLfahE9uFoUruu/s1600/IMG_4935.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisCe_XzmlWn-hMcYayZnKToaTxP5aJnzKRocfdLtVKt4C-tfsT7BOIxZrBYneS2FIJhViSpxH0HaFPLENRb2fxBNnYkOqgc4JhJXv_biG5mGXTV8HI5bwC-mXLfahE9uFoUruu/s640/IMG_4935.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bole, the cosmopolitan heart of Addis Ababa</td></tr>
</tbody></table>
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.<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-76770827721911759732016-12-08T00:23:00.000+00:002016-12-08T00:23:55.161+00:00Operator overloading in SwiftAfter years of having to write <i>[@"bar" isEqualToString:@"foo"]</i> I’m delighted that in swift we can simplify things and just write <i>“bar” == “foo”</i>.<br />
<br />
However there is an important thing to note. Swift will match the overloaded operator to function that takes the same arguments. Simple.<br />
<br />
So if I follow the example set by the equatable protocol, and wanted to compare two <i>NSObject</i> subclasses, I could create a function that looks something like:<br />
<br />
<script src="https://gist.github.com/veritech/7c6f8f5aa6b59fa218dc234ebf0675b2.js"></script>
And this would work everywhere as expected and print “hello world” …<br />
<br />
Well, no. Remember I said exactly the same arguments.<br />
<br />
So, If I was to change the optionality of one of the variables:<br />
<br />
<blockquote class="tr_bq">
let a = Object(name: "foo")<br />
var b:Object?<br />
<br />
b = Object(name: "foo")</blockquote>
<br />
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 <i>doSomethingWhenTheStringChanges</i> would never be called.<br />
<br />
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.<br />
<br />
<script src="https://gist.github.com/veritech/82c073e862e1885867dd316474a2847d.js"></script>
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.<br />
<br />
What makes this behaviour particularly “special” is that it will only happen with <i>NSObject</i> 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.<br />
<br />
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.<br />
<br />
It should also be noted that Xcode correctly syntax highlights the operator depending on whether you will use <i>NSObject</i>’s version of isEqual: or your own at runtime, but there is no warning.Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-61112842788345464012016-01-11T13:59:00.000+00:002016-01-11T14:00:29.974+00:00Taking back disk space from XcodeI 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.<br />
<br />
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.<br />
<br />
After digging around a little, I discovered that the <b><i>~/Library/Developer</i></b> folder is weighing in at 35.75GB, thats 13% of my disk space!<br />
<br />
Digging a little deeper, <b><i>~/Library/Developer/Xcode/iOS DeviceSupport/</i></b> 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.<br />
<br />
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 <a href="http://stackoverflow.com/questions/27614197/duplicate-iphone-simulators-appeared-on-my-xcode">stackoverflow post</a> 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.<br />
<br />
The above tips helped me recover 22 GB just from Xcode.<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-80971765887540179492015-11-13T11:39:00.002+00:002015-11-13T11:42:41.996+00:00My public keyI'm not quite sure why, but it's taken me a life time to setup encrypted email. Below is my Public key, email away.<br />
<br />
<br />
<script src="https://gist.github.com/veritech/64358a6c5a5abe84e395.js"></script>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-11390908785909224012014-10-24T12:23:00.000+01:002014-11-05T21:53:10.631+00:00Making a numeric/pin pad with NSLayoutConstraints<br />
NSLayoutConstraints are awesome. But like many cocoa technologies (strangely, all the ones that I like) the learning curve is fairly steep.<br />
<br />
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.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzIgj5RjFSl_uZoSyFEA9-ndSJT1sTYnAok_7Vj002gIfwPLteh0t4HRuG8pfhaaW5vEmTzXwRv55AT2YdwQ_OT8fWbjB-st-XfYJd6yqWXilB-CeKlesTXQn6Bk-Gjh39ZoRG/s1600/Screen+Shot+2014-10-24+at+12.10.44.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzIgj5RjFSl_uZoSyFEA9-ndSJT1sTYnAok_7Vj002gIfwPLteh0t4HRuG8pfhaaW5vEmTzXwRv55AT2YdwQ_OT8fWbjB-st-XfYJd6yqWXilB-CeKlesTXQn6Bk-Gjh39ZoRG/s1600/Screen+Shot+2014-10-24+at+12.10.44.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
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".<br />
<br />
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.<br />
<br />
Like 99% of cocoa code, it's not concise. Disfrutarlo!<br />
<script src="https://gist.github.com/veritech/3005788135ecf241e52f.js"></script>Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-35878722281142548282014-07-07T01:35:00.000+01:002014-07-07T01:35:13.919+01:00Future by DesignAs a child I loved popular science magazine. Mainly because I was busy designing the future of space propulsion. Hint, it used "controlled" nuclear explosions.<br />
<br />
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.<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/bwJaLFMf7IA" width="100%"></iframe>Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-3388845934865855492014-02-11T01:51:00.002+00:002014-02-11T01:58:27.620+00:00Filing Corporation Tax: CT600I've been running my own UK Private limited company for a few years now. Because I'm cheap, I do my taxes myself. Usually from a location that would be considered glamorous by UK standards. As such calling the support line isn't really an option.<br />
<br />
In recent years I've had a number of issues downloading the CT600 form. If you want to file independently you have to do it via this form, there is no alternative. This of course creates an issue if your nearing the deadline, and can't access the form.<br />
<br />
If you happen to be having issues I have a single tip for you. Private browsing mode. Works for me every time.<br />
<br />
Happy Tax filling day.Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0Bogotá, Bogota, Colombia4.5980555999999986 -74.07583333.5847115999999986 -75.3667268 5.6113995999999986 -72.7849398tag:blogger.com,1999:blog-12539200.post-64026157890926701452014-01-07T13:15:00.000+00:002014-01-13T03:14:51.229+00:002014: Feliz Nuevo Año<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB8MpdUELGSMhuvx6Mf5z8O93kmEURSpdDFhyphenhyphen2DHJKgLggngkE2FgaUajigamjWgD0s7Urp3pc4eFZhpZoudpXDqpFTazvzpbBCmUfn35YPLYg_SQtXkMCmcaVd5-hgH8NvC_6/s1600/IMG_1997.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB8MpdUELGSMhuvx6Mf5z8O93kmEURSpdDFhyphenhyphen2DHJKgLggngkE2FgaUajigamjWgD0s7Urp3pc4eFZhpZoudpXDqpFTazvzpbBCmUfn35YPLYg_SQtXkMCmcaVd5-hgH8NvC_6/s1600/IMG_1997.JPG" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A Kite Surfer in Cabo de La Vela, Colombia</td></tr>
</tbody></table>
While I doubt 2014 will mean that I suddenly start posting on a regular basis. For my millions of readers, Happy New Year.Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0Barranquilla, Atlantico, Colombia10.9642103 -74.79704349999997210.7148298 -75.119766999999968 11.213590799999999 -74.474319999999977tag:blogger.com,1999:blog-12539200.post-89882466672231356262013-12-21T12:13:00.001+00:002013-12-21T12:13:18.845+00:00What a difference 3 years makesIn October of 2010 I came up with the bright idea to move to Sevilla, Spain.<br />
Everything I knew about the City came from combination of wikipedia, Wikitravel & Google Earth. I packed my bag and got on a plane.<br />
<br />
The sun shone, the drink flowed, I loved it.<br />
<br />
But sadly, after only 6 weeks I decided to come home after a death in my Family. After 5 months back in England I had had enough, and set off again. Final destination unknown. This time I didn't come back for over 2 years.<br />
<br />
Fast forward to today, 3 years later. I'm about to (try to) move to Bogota, Colombia. The situation is different this time around. I'm older (yay), I've seen a lot more of the world, I've actually visited the city before, and more importantly I can buy an Ice cream without resorting to Chinese.<br />
<br />
What a difference 3 years makes.<br />
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-19982326630138886402013-08-15T10:16:00.000+01:002013-08-15T10:16:16.566+01:00Vida en Venezuela - Parte 2, Caracas<div class="p1">
With our stamps in hand, we re-entered colombia (illegally) and got our bags and supplies for the bus trip. The bus was supposed to leave Maicao for the border at 4pm were we would then change onto another bus and then head for the capital. We didn't leave 7:45pm.</div>
<div class="p2">
<br /></div>
<div class="p1">
As soon as the bus left the carpark, which was located between the Colombian and Venezuelan border checkpoints the driver opened the door to the cabin and announced that if we wanted to leave quickly he would need 400VEF (US$12) bolivars so we could skip the queue of other buses ahead of us at the border checkpoint. A lady in the front row stood up and took a collection among the passengers, there were no complaints, just people requesting change for smaller bills.</div>
<div class="p2">
<br /></div>
<div class="p1">
Once the collection was complete, she counted the cash in front of everyone, took out 400 and counted the remaining bills, and announced the total to the bus, handed off the 400 to the bus driver, put the rest in her bag and took her seat. Just like the driver promised we whizzed past the other buses and started on our way.</div>
<div class="p2">
<br /></div>
<div class="p1">
I don't know what it was about our driver but he constantly had the look of someone who had a gun to his head. His eyes were wild, and his thin frame didn't help him appear any more settled with his surroundings. In retrospect if I had to drive a bus in the middle of the night to a city with 2700+ murders a year I would be a little gaunt too.</div>
<div class="p2">
<br /></div>
<div class="p1">
The money that was left over from the initial collection was not for the lady, but for the buses "bribe fund". I discovered this at the next checkout when the driver opened the door and requested the remainder of the funds from the lady. At the subsequent checkpoint he made a another request for funds , with our initial fund being exhausted he started at the back of the bus and worked his way to the middle before deciding he had a enough "lubricant" for this particular situation.</div>
<div class="p2">
<br /></div>
<div class="p1">
Just before we crossed the longest concrete bridge in the world we were stopped again. This time a for what ever reason a bribe would not work. We were ordered off the bus, and our identification and visa stamps checked to ensure we were there legally.</div>
<div class="p2">
<br /></div>
<div class="p1">
After this point I became extremely paranoid, I split my cash across my bags and wallet, I hid my USD in my underwear, and prepared a "disposable" wallet with about $40 and some debit cards. I had heard stories of buses being hijacked in safer countries than here, but i had never felt so unsafe during my time in South America until now.</div>
<div class="p1">
<br /></div>
<div class="p1">
Throughout the rest of the night, every time the door would open, which it did often as it didn't lock properly I would prepare myself to be stormed by paramilitaries with AK47's.</div>
<div class="p1">
<br /></div>
<div class="p1">
After 15 hours or so I found myself at La Bandera Bus station in Caracas, where the walls are papered with Nationalist rhetoric, like the "people are the heart of the country" and "Chavez said Maduro should be the leader". After a quick costume change we made a quick attempt to get a refund for our return ticket to Maicao, but either the tiredness or the complete lack of good spanish meant that we failed to get it. After a brief sweep of the Station we determined that we could not get to the east of the country from La Bandera. I was tempted to use our fake reservation at a Hotel in Caracas, but at the same time I was cognisant of the fact that this was Caracas. So we did the clever thing and got in a unlicensed taxi and made our way to Terminal de Oriente.</div>
<div class="p1">
<br /></div>
<div class="p1">
Hector, our cab driver gave us the quick low down on the city. He works in Caracas, but doesn't live there as it's too dangerous. Instead he lives 45 minutes away in a suburb. Traffic during the week is awful, but this was a Sunday so it was fairly clear. He also showed us the most dangerous barrio in the city. 200 (USD$8) Bolivars later we arrived at Terminal de Oriente. We found a bus heading to the south-east of country, Vladimir was heading to Santa Elena, while I was going to Ciudad Bolivar. The ticket was 200 Bolivars, which doesn't quite make sense given that the taxi ride was so expensive, but hey it's USD$8. We had to wait for 4 hours before the bus left so we settled in with some tripe soup and roast chicken.</div>
<div class="p1">
<br /></div>
<div class="p1">
An hour into our wait, Vladimir discovered that there was flight to Rio from Caracas for US$100 after currency tricky was applied and made a mad dash for the airport. I charged my phone, bought some water, and continued to wait.</div>
<div class="p1">
<br /></div>
<div class="p1">
That was Caracas.</div>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com1Maicao, La Guajira, Colombia11.3777778 -72.238888911.3777778 -72.2388889 11.3777778 -72.2388889tag:blogger.com,1999:blog-12539200.post-17721748112868554722013-08-15T10:10:00.001+01:002013-08-15T10:10:26.321+01:00Thats a lot of lines<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyi8qlxSoj9b-MXPyFrReYvtfq54C-bhcv-uUXSA6IjIpEDVNgweGQUjAe6rM9sGaKiw6GH0JrFh_Eil_wDOZl5yrn9gKNV0ootOioc8STxnY8ExcH8d5kIrWZjLpG4t6dOpnp/s1600/map.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyi8qlxSoj9b-MXPyFrReYvtfq54C-bhcv-uUXSA6IjIpEDVNgweGQUjAe6rM9sGaKiw6GH0JrFh_Eil_wDOZl5yrn9gKNV0ootOioc8STxnY8ExcH8d5kIrWZjLpG4t6dOpnp/s640/map.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">My Journey(s) of the last two years</td></tr>
</tbody></table>
<br />
I arrived back in England this past tuesday. Almost a year since I was last here, and well over 2 years since I left. It's been two days, and quite frankly I'm dreaming about leaving again.Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-24431510287690466572013-06-29T17:35:00.001+01:002013-06-29T17:35:25.090+01:00Unique objects with Core Data: Find and CreateI don't think it's a secret that I love Core Data. It's my opinion that the people who don't like it or use it are either very stupid or extremely smart.<br />
<br />
There is one problem that has plagued me for years, how to ensure that when i'm perform imports I don't create duplicate objects. In reality the problem is fairly simple conceptually, you create a hash table, and then hash the Incoming objects to test for their membership in the set, Easy.<br />
<br />
But if you believe in DRY, the problem is then making this unique constraint checking code modular and portable across projects, and different Core Data Models.<br />
<br />
The first issue we need to is identify what property of a NSManagedObject should be unique relative to the rest of the greater set. We can achieve this by adding a class method to the NSManagedObject class<br />
<code><br /></code>
<code>+ (NSString *)uniqueKeypath {<br /> return nil;<br />
} </code>
<br />
<code><br /></code>
However, in an more advanced model there might be multiple properties that need to be evaluated to determine if an object is unique so …<br />
<code><br /></code>
<code>+ (NSArray *)uniqueKeypaths {<br /> return nil;<br />
}</code>
<br />
<code><br /></code>
It's important to note that since we are using Keypaths, we can actually evaluate the values of related entities.<br />
<h2>
Finding a Needle in a Haystack</h2>
Now it's time to make the magic happen. We apply the concept, we create a hash table, then lookup the unique value of the new objects in the table. If we get a 'hit', we don't do anything, if we 'miss' we create a new object. The sudo code is effectively.<br />
<code><br /></code>
<code>
FOR EACH object IN newObjects:<br />
<br /> IF NOT object IN allObjects:<br />
<br /> createObject(object)<br />
</code>
<br />
<code><br /></code>
The above is simplistic, but you get the point. However you should have made the observation, that if we do it exactly like this, it will not only take ages but we'll run out of memory long before we've began doing the comparison object if we have an extremely large set.<br />
<br />
So, the solution is GCD and batched fetching. Given that we can assume that only one import is happening at any one time. So once we have performed the initial fetch of all the existing objects, we can split the comparison operations for each of the new objects on to a concurrent GCD queue. We also need a place to store the objects that need to be created, rather than copying them into another collection, we can keep the current collection and gather the indexes of all the new objects, and then create a subset of the superset.<br />
<code><br /></code>
<code>
//Compare new hashes against all the known hashes on multiple threads<br />
dispatch_apply([newObjects count], concurrentQueue, ^(size_t idx) {<br /><br /> //Note that everything that happens here is on a concurrent queue<br /> if (![hashes member:[[newObjects objectAtIndex:idx] valueForKeyPath:aKeypath]]) {<br />
<br /> //We have synchronize access to the mutable indexset<br />
<br /> [lock lock]; //Lock the index set<br />
<br /> [uniqueIndexes addIndex:idx]; //add the unique index<br />
<br /> [lock unlock]; //Unlock the index set<br /><br /> }<br /><br />
});
</code>
<br />
<code><br /></code>
In this case I'm using dispatch_apply (which I personally think is awesome). It will spawn multiple instances of the block on a concurrent queue. Because of the concurrent nature of this method it's important that we lock the NSMutableIndexSet to ensure that it doesn't blow up when two indexes are added at the same time. The current implementation with a simple NSLock results in poor performance on the initial import as every single block will attempt to get the lock so they can add an index. One possible solution is to use a serial dispatch queue to handle the adding of the indexes, and call it via a dispatch_async.<br />
<br />
The next part is to split the work of fetching the objects in to smaller batches so we can not only perform smaller units of work, but also have a lower high memory watermark. NSFetchRequest has support for batching requests so this is apparently handled transparently to the rest of the code using a special type of NSArray. However I haven't tested this to ensure it behaves as I expect.<br />
<br />
I've posted an implementation as a abstract subclass of NSManagedObject on <a href="https://github.com/veritech/NSManagedObject-unique">Github</a>, fork away!<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0Cusco, Peru-13.525 -71.972222199999976-13.648504 -72.133583699999974 -13.401496 -71.810860699999978tag:blogger.com,1999:blog-12539200.post-38431174576621234932013-06-25T16:33:00.003+01:002013-06-25T22:52:35.745+01:00Vida en Venezuela - Parte 1, Colombia a Venezuela<div class="p1">
While several services offered buses "directo" to Maracaibo, most of those arrived at night, which is a crappy even in the nicest cities/ countries, never mind Venezuela.</div>
<div class="p2">
<br /></div>
<div class="p1">
So I formulated a plan, that only really worked based on geography. I would do the long jaunt from Cartagena to Riohacha. Bed down there for a night and then set off early the next morning.</div>
<div class="p2">
<br /></div>
<div class="p1">
From the bus station in Riohacha I got a bus for 8000 COP to Maicao, the major border town. The journey took a little over an hour. As soon as I got off the bus in Maicao I was accosted by several people offering me a service to Maracaibo. Wildly pointing to a bunch of beaten up American gas guzzlers from the 70s & 80s, the "por puestos".</div>
<div class="p2">
<br /></div>
<div class="p1">
As I would discover later, there is no direct bus service to Maracaibo from Maicao, however you can reach other destinations deeper in Venezuela from here namely Caracas, a city that commonly has 20 murders a day.</div>
<div class="p2">
<br /></div>
<div class="p1">
I jumped in one of these beaten up Chevys and paid USD$12 or 20000COP and prepared myself for the adventure. The taxi stops at the Colombian immigration office and lets out those who want to get their exit stamp. Once at the office there is usually a line that takes anywhere from an hour upwards to navigate. As a result of this constant people presence there are plenty of people offering cambio services for both COP and USD, the rate for the latter being better than former. Having said that, both rates are no where near as good as what you would get once your in the country proper.</div>
<div class="p2">
<br /></div>
<div class="p1">
After reaching my turn at the head of the queue, things started to go off script. The Colombian immigration official suggested that I go over to the Venezuelan side first and see if they would let me in before stamping me out of the country. Strange, but ok this is Bolivarian Republic, strange is just the beginning of normal.</div>
<div class="p2">
<br /></div>
<div class="p1">
10 minutes later I found the Venezuelan immigration office, complete with a long line of its own. After queuing for around 30 minutes I again reached the head of the line, and shoved my documents through the tidy window and crouched down so the socialist AC could cool my capitalist face.</div>
<div class="p2">
<br /></div>
<div class="p1">
It took a while for the officer to respond to my documents as he was busy receiving documents with his left hand, and pocketing cash with his right hand. However after a minute or two he took my passport and began to analyse it. After a brief flick through he threw it back on the counter coupled with a loud "NO STAMP". Somewhat expected, to be honest but by this time my patience was wearing thin, and waiting in the Colombian border line again didn't seem like something I wanted to. So I decide I had 3 choices.</div>
<div class="p2">
<br /></div>
<div class="p1">
* Go back to colombia and get an exit stamp and try again.</div>
<div class="p1">
* Bribe the Venezuelan immigration official</div>
<div class="p1">
* Enter Venezuela illegally, and then come back tomorrow and sort this nonsense out.</div>
<div class="p2">
<br /></div>
<div class="p1">
There was also a fourth option which was entering illegally travelling across the country, without technically having left colombia, see angel falls and then return back across the same border crossing without visiting either nations immigration service. The problem with this is that i would need to bribe every single official i met, an expensive proposition in a country where I can't use an ATM.</div>
<div class="p2">
<br /></div>
<div class="p1">
I opted for option 2, the bribe.</div>
<div class="p2">
<br /></div>
<div class="p1">
Bribing is something I'm fascinated by but have no real understanding of in a practical sense. The thing that I really don't get is how does one calculate how much is required to make someone look the other way. Especially when you take into consideration that your bribe might be accepted but your wishes not carried out.</div>
<div class="p2">
<br /></div>
<div class="p1">
After a little self deliberation I determined that USD$5 was an acceptable amount of money to lose, while also being (just) enough to encourage someone to look the other way. Now the next problem was how to deliver it. While I knew that the officer could be bought, I didn't know if he wanted to maintain a legit appearance to his colleagues, so simply sliding some money across the counter might not only annoy him, but also the people in the queue behind unable to "splash out" in a similar fashion.</div>
<div class="p2">
<br /></div>
<div class="p1">
I wrapped the bill around my immigration form, inserted it in my passport and rejoined the queue. 45 minutes later my attempt was rebuffed with a firm NO, and a return of my money.</div>
<div class="p2">
<br /></div>
<div class="p1">
By this time it was about 2pm, I had been awake since 7am, barely eaten anything and had been standing in the sun for most of the day. I was dog tired.</div>
<div class="p2">
<br /></div>
<div class="p1">
I headed back to Colombian immigration to get my exit stamp and try again, with slightly more complete papers. Whilst waiting in line for the second time I spotted two gringos. Their pale skin and failure to adhere to the local dress code made them stick out, for the record I was wearing jeans, shoes, and a t-shirt the Colombian dress code. An hour later I had my exit stamp in hand, and had met the aforementioned gringos, a French girl and a Canadian boy.</div>
<div class="p2">
<br /></div>
<div class="p1">
Needless to say I was rejected again, the officer (the same one I had tried to bribe earlier in the day) had shown me a sign this time instructing me to have a notarised invitation or hotel reservation and land/ air tickets out of the country. By this time it was around 5pm. For one reason or another the French lady was accepted without any of the aforementioned documents, but the Canadian was also rejected, with the aforementioned documents. Since we were both wallowing in rejection, Vladimir (the Canadian) and I decided to get a taxi back to Maicao. With the intention of starting bright and early the next day.</div>
<div class="p2">
<br /></div>
<div class="p1">
We were out of the hotel by 8 am the next day and made a beeline for the bus station on the edge of town. Our plan was simple, we would buy a return ticket to Maracaibo and fabricate a hotel reservation in the city to please the immigration officers. We couldn't just book one, as paying for anything in Venezuela with bolivars not exchanged at the black market rate is 400% more expensive.</div>
<div class="p2">
<br /></div>
<div class="p1">
However at the bus station we discovered that no company offered service to Maracaibo, only Caracas, the most dangerous city in the world ... So we got a ticket that returned 3 days later for 70000cop and jumped on a couple of Moto taxis for the border.</div>
<div class="p2">
<br /></div>
<div class="p1">
We stamped out of colombia, again and then headed for the Bolivarian republic. After queuing in the nervously for about 30 minutes we reached the front ... Only to be greeted by the same official as yesterday. Seeing a only a handful of foreigners had used that crossing in the last few days he remembered as both. The guy said no almost immediately, but we insisted in the most broken Spanish ever that we had all the documents. Eventually he told us to move to the side and enter the immigration office using a side entrance.</div>
<div class="p2">
<br /></div>
<div class="p1">
Once inside we explained to the Jefe (The boss) that we had reservations along with bus tickets. It wasn't going too well until we explained that we also had return tickets to maicao leaving the day out reservation ended. Suddenly the mood changed, "yep that's great, I'll go stamp them then." And with that we were in.</div>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com1Maicao, La Guajira, Colombia11.3777778 -72.238888910.3816568 -73.5297824 12.373898800000001 -70.947995400000011tag:blogger.com,1999:blog-12539200.post-28673832902210597442013-04-13T23:13:00.002+01:002013-04-13T23:13:45.030+01:00ITAP: Inca Trail edition<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPprERbGQ8e_5pM_GrVbb0C86h_49zhEh-2Bb2EkybjJAFWe0v5PxOgUGXtAcotH7a-T85GeksXU29rDCsB2yhZqv5aGVWMwEMp-i6l8xHVDt1fxOruX0CsJ0zHO5uZLJ6aGVl/s1600/SAM_5245_fused.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPprERbGQ8e_5pM_GrVbb0C86h_49zhEh-2Bb2EkybjJAFWe0v5PxOgUGXtAcotH7a-T85GeksXU29rDCsB2yhZqv5aGVWMwEMp-i6l8xHVDt1fxOruX0CsJ0zHO5uZLJ6aGVl/s640/SAM_5245_fused.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Somewhere in Andes</td></tr>
</tbody></table>
<br />Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-66166945691709189932013-03-17T23:28:00.000+00:002013-03-17T23:28:05.547+00:00FRCoreDataExportOperationCore Data is possibly one of the most useful frameworks in iOS. People have different feelings towards it, but i'm a solid fan. One issue that i'm sure everyone has had with core data at one point or another is getting data in and out of Core Data. This ultimately led to creation of the <a href="https://github.com/veritech/FRCoreDataOperation"><i>FRCoreDataOperation</i></a> project.<br />
<br />
A few months ago I started using <i>FRCoreDataOperation</i> to serialize Core Data objects to disk. Sure you could do this with plists, but thats a little too restrictive especially if you want the serialized data to be compatible with other applications and platforms. Usually my format of choice is CSV, as you can import it into excel/ google docs easily, also python has a great module for loading CSV data.<br />
<br />
For another project I found myself needing to do the same thing again, the classic sign that it was time to do make something reusable and adaptable. So <i>FRCoreDataExportOperation </i>was born. <i>FRCoreDataExportOperation</i> is a concrete subclass of <i>FRCoreDataOperation</i> and can be used without subclassing. Below is an example of how you use the class.<br />
<br />
<script src="https://gist.github.com/veritech/5183956.js"></script>
There are a series of initializers that you can use in tandem with the class, but the one you'll probably most interested in is below.<br />
<br />
<script src="https://gist.github.com/veritech/5184051.js"></script>
As you can see by using a predicate and sort descriptors along with the entity name you can select the objects you want to export. The export operation also supports relationships, it's not completely recursive, and will only explore entities that have a direct relationship with the entity you specified.<br />
<br />
The next step is to select a formatter, the actual serialization format is completely abstracted from the class and is performed by the object assigned to <i>FRCoreDataExportOperation's</i> entityFormatter property. Thus far i've only created the <i>FRCoreDataEntityFormatter</i>, <i><a href="https://github.com/veritech/FRCoreDataOperation/blob/master/FRCoreDataEntityFormatters/FRCSVEntityFormatter.h">FRCSVEntityFormatter</a>, </i>but you can create your own by implementing the <a href="https://github.com/veritech/FRCoreDataOperation/blob/master/FRCoreDataEntityFormatter.h"><i>FRCoreDataEntityFormatter</i></a> protocol.<br />
<br />
The <i>FRCSVEntityFormatter </i>is somewhat customizable, and allows you to specify a <i>NSArray</i> with the keypaths that you want to be serialized to disk. The columns will be written in the order they appear in the array. If you choose to use the formatter without a whitelist, all of the properties will be written in the alphabetical order of the property name.<br />
<br />
Best of all you can get this for yourself via Cocoapods, pod is aptly called <b><i>FRCoreDataOperation</i></b><br />
<b><i><br /></i></b>
Happy exporting<br />
<br />Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-48848288668956209672013-03-05T20:23:00.001+00:002013-03-05T20:23:29.510+00:00Stars!During a chat with some of my colleagues I remembered one of my favourite games, <a href="http://en.wikipedia.org/wiki/Stars!">Stars!</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0uBeM7wAgmGLsijiUdsIHBbVq39qGtr4GVQuuyzkMIXMO0hD0JJklG-OZ39R2r4pzNM1eKBarRHEWhSuwMr0JRyYmEadsWC9cosYTLJQBSv2Ez4ueuBF40mcx2Te4NmuJkoZ9/s1600/Screen+Shot+2013-03-05+at+12.10.53.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="420" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0uBeM7wAgmGLsijiUdsIHBbVq39qGtr4GVQuuyzkMIXMO0hD0JJklG-OZ39R2r4pzNM1eKBarRHEWhSuwMr0JRyYmEadsWC9cosYTLJQBSv2Ez4ueuBF40mcx2Te4NmuJkoZ9/s640/Screen+Shot+2013-03-05+at+12.10.53.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
The concept was simple, you start with a single planet, and then expand across the universe, encountering new technologies and races as the years pass. In many ways it's a fantastically engineered game. It's UI works just as effectively at 640x480 as it does at 2560x1600, It never crashes, it uses a small amount of memory and turns are quick, even with a 33Mhz CPU.<br />
<br />
Despite it's basic appearance, it's extremely addictive. If you want to play it yourself you can find serial numbers and download links <a href="http://www.starsfaq.com/download.htm">here</a>.Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-80309942185862796032013-03-01T02:06:00.001+00:002013-03-01T02:07:35.582+00:00Building Git on OSX<div>
Getting this error message when running make with a fresh clone of the git source code?</div>
<br />
<code>GIT_VERSION = 1.8.2.rc1.19.g443d803<br />
* new build flags<br />
CC credential-store.o<br />
In file included from credential-store.c:1:<br />
In file included from ./cache.h:8:<br />
./gettext.h:17:11: fatal error: 'libintl.h' file not found<br />
# include <libintl.h><br />
^<br />
1 error generated.<br />
make: *** [credential-store.o] Error 1<br />
</code>
<br />
<div>
<br />
The solution is to disable this the component, which can be done by creating a <b><i>config.mak</i></b> file in the same directory with the following contents:<br />
<br /></div>
<code>
NO_GETTEXT = 1;</code>
<br />
<div>
<br />
Your welcome</div>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com1tag:blogger.com,1999:blog-12539200.post-56343648291769651522012-11-13T06:03:00.001+00:002012-11-13T06:03:59.390+00:00When Magical Record stops being magicalSome time ago i discovered <a href="https://github.com/magicalpanda/MagicalRecord">Magical Record</a>. It offers some fantastic categories to help you setup your Core Data stack with a single line of code. But it's much more than a Core Data boilerplate thingy. It also offers a range of Active Record pattern like shorthand methods. For example you can find all the instances of a particular type of object without having to write your own <i>NSPredicate</i> and <i>NSFetchRequest</i> using <i>MR_findAll</i>.<div>
<br /></div>
<div>
Somewhat recently they moved to version 2.0, along with lots of others features they added support for Nested object contexts. If you haven't read about nested/ parent-child managed object context your missing out, especially if you've ever tried to use Core Data with multiple threads.</div>
<h3>
So when did it stop becoming magical?</h3>
<div>
Usually i use Magical Record to setup my core data stack, and take advantage of its singleton default context, for those times when i'm too lazy to pass it around like a good engineer. I've also been known to dabble a little with it's Active Record implementation.</div>
<div>
<br /></div>
<div>
However with 2.0, the developer(s) have chosen to change the internal structure slightly. A "Root" context is created at the top of the tree, this has a child context that is returned when you call the <i>MR_defaultContext</i> method. The root context controls the writing of data to disk. This means that if you attempt to save the <i>MR_defaultContext</i> your changes are not persisted to disk, but instead pushed up to the root context.</div>
<div>
<br /></div>
<div>
Well that awesome, right ...</div>
<div>
<br /></div>
<div>
Well it is, if it was obvious. Instead I was left no errors, an empty sqlite db, and no data. Personally I really think they should have just made the <i>MR_defaultContext</i> the root context, and allowed users to nest contexts themselves if they wish. In case your interested you can reach the 'Root' context by calling <i>MR_rootSavingContext.</i></div>
<div>
<br /></div>
<div>
Anyways after digging around the source code, and a little RTFM I discovered that in order to actually persist your data to disk you have to call <i>MR_saveNestedContexts</i>. This method will recursively call up the tree and save each context. Neat, but not obvious, especially when the API convention is to simply call the native <i>save:</i></div>
<div>
<i><br /></i></div>
<div>
So really this post exists to say, if your a fan of Magical Record and your pulling your hair wondering why <i>save:</i> has stopped working the answer is use <i>MR_saveNestedContexts.</i></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com2San Francisco, CA, USA37.7749295 -122.419415537.6745235 -122.577344 37.8753355 -122.261487tag:blogger.com,1999:blog-12539200.post-90703612680069597562012-10-18T23:17:00.004+01:002012-10-18T23:17:53.708+01:00Drawing UIImage's with blocksI have a slight love affair with Quartz's drawing routines. I don't know what it is about them, but there is something I love about stroking rects and filling paths. It's like OpenGL for stupid people.<br />
<br />
Anyways, during my love affair I got bit annoyed at having to subclass <i>UIView</i> every time i wanted to make a quick sprite, or overlay a one image on top of another.<br />
<br />
<i>CALayer</i>'s a are awesome and everything, but i still need to subclass <i>UIView</i> unless i want a bunch of layout mess every where.<br />
<br />
So I thought wouldn't it be cool to be able to create <i>UIImage'</i>s quickly and then just throw them into a <i>CALayer</i>s or <i>UIImageView</i>'s and worry about the rest later.
<script src="https://gist.github.com/3915021.js"> </script>
<br />
The above does just that, you give it a canvas size or more informally the size of the <i>UIImage</i> that you wish to generate.<br />
<br />
It will create the <i>CGBitmapContext</i> with a RGB colorspace, and then you can draw to your hearts content.<br />
<br />
You can treat the block almost like a you would <i>drawRect</i>. I say almost because it's not inserted into the graphics context stack, so some of the helper methods like <i>[[UIColor blackColor] setFill]</i> will not work, and you'll have to learn how to do it the 'proper way' (<i>CGColorSetFillColor</i>()). Just consider it a general rule, that if it renders something and doesn't take a <i>CGContextRef</i> you need an alternative method to use it inside this block.Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0San Francisco, CA, USA37.7749295 -122.419415537.6745235 -122.577344 37.8753355 -122.261487tag:blogger.com,1999:blog-12539200.post-88902309388510654032012-09-23T00:00:00.001+01:002012-09-23T00:00:49.949+01:00The evolution of lazy initialization<div><a href="http://en.wikipedia.org/wiki/Lazy_initialization">Lazy initialization</a> is tent pole of Objective C. Apple placed a lot of emphasis on using the pattern in the early iPhone days. That was justified especially considering that the original iPhone shipped with 128MB of RAM, compared to the latest iPhone 5 with 1024MB of RAM.</div>
<h2>In the beginning</h2>
<script src="https://gist.github.com/3765043.js"> </script>
<br />
<h2>The ARC evolution</h2>
<script src="https://gist.github.com/3765057.js"> </script>
<br />
<div>The ARC evolution was fairly tame, allowing us to move the ivar into the implementation files. While the original method was great, and served me well until ARC. With no need to dealloc, and the ability to have iVars that aren't declared in the public interfac.</div>
<h2>Clang takes it up a notch</h2>
<script src="https://gist.github.com/3765074.js"> </script>
<br />
<div>With the most recent versions of Clang you no longer have to use the <em>@synthesize</em> & <em>@dynamic</em> keywords when making <em>@property</em> declarations.</div>
<div>This is all well and good, but I don't want to write my own ivars if I don't have to. So I've set about exploring ways that I can do away with having to create my own ivars.</div>
<h2>Option 1.</h2>
<div>This approach is comprised of three steps</div>
<ol>
<li>Public readonly property declaration</li>
<li>Private readwrite property (re)declaration in a class extension</li>
<li>Assign our instance to the ivar</li>
</ol>
<script src="https://gist.github.com/3765174.js"> </script>
<br />
<div>The problem with this is that there is still the ability to overwrite the ivar. Granted it's only from within the class, but still not ideal. This could be an advantage as if you decide to move away from the pattern all you need to do is set the ivar via the mutator.</div>
<h2>Option 2.</h2>
<div>Another alternative, is to take advantage of another clang feature, where we use the <em>@synthesize</em> directive, to generate a backing ivar on request, without having to explicitly declare the ivar, or at least declare it in a conventional way.</div>
<div>Along with being the smallest version, we can specify the format of our private ivars, so if you want to suffix your underscore rather than prefix it, you have that option.</div>
<script src="https://gist.github.com/3765180.js"> </script>
<h2>Whats the solution?</h2>
<div>Quite frankly, i don't know. I'm leaning towards Option 2 as it doesn't provide an mutator for the ivar, and so there is almost no suggestion that the ivar should be mutated by anything thing other than the lazy accessor. However I'm interested to hear the opinions of others.</div>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0San Francisco, CA, USA37.7749295 -122.419415537.6745235 -122.577344 37.8753355 -122.261487tag:blogger.com,1999:blog-12539200.post-63594102833189011612012-09-20T00:40:00.000+01:002012-09-20T00:41:04.340+01:00I Took a Picture [Cambodia Edition]<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5ZdAq31xn3Bz2ZEq06B1bNdMSW4pCOTiVzce_bT2qfmIeza3WLHTGeDkI7jt2PB0A_CrlHXVYvTujhCMAhWsPtVjDcuTEX7_qL6fDFrkO1IqAn9o3mudc54l3WDJ2CXIBVHLA/s1600/SAM_2718_tonemapped+copy.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5ZdAq31xn3Bz2ZEq06B1bNdMSW4pCOTiVzce_bT2qfmIeza3WLHTGeDkI7jt2PB0A_CrlHXVYvTujhCMAhWsPtVjDcuTEX7_qL6fDFrkO1IqAn9o3mudc54l3WDJ2CXIBVHLA/s640/SAM_2718_tonemapped+copy.jpg" width="419" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A sunset in Sihanoukville, Cambodia</td></tr>
</tbody></table>
Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-69037906998960791372012-09-20T00:06:00.000+01:002012-09-20T00:28:05.754+01:00Social.framework
<div>
It feels like an eternity since it was announced but iOS 6 is finally available to
the masses, and we can now talk about the all the (few) new goodies that it
contains.<br />
Apple included the Social Framework in iOS 6 as an abstraction layer for accessing
the various social services that are now included with iOS. The key feature here is
that you never have to deal with the Facebook SDK again if you wish...<br />
So let's explore how you can use the new Social framework classes to replace REST API
access functionality that is provided via the Official Facebook SDK
</div>
<div>
TL;DR; <a href="https://gist.github.com/3752113">Sample code</a>
</div><br />
<h4>Create an ACAccountStore</h4>
<div>
According to Apple's developer documentation the ACAccountStore
</div>
<blockquote class="tr_bq">
<div class="p1">
[ACAccountStore] provides an interface for accessing, manipulating, and storing
accounts. To create and retrieve accounts from the Accounts database, you must
create an <em>ACAccountStore</em> object. Each <em>ACAccount</em> object belongs to
a single <em>ACAccountStore</em> object.
</div>
</blockquote>
<div>
A simple <em>alloc</em> && init sent to ACAccountStore will suffice. Perhaps
the easiest thing you'll do this week.
</div><br />
<h4>Get the Facebook ACAccountType</h4><script src="https://gist.github.com/3752770.js"
type="text/javascript">
</script>
<div>
The 2nd easiest thing you'll do this week
</div><br />
<h4>Request access to currently logged in Facebook User</h4><script src=
"https://gist.github.com/3752567.js" type="text/javascript">
</script>
<div>
Before the callback block is called the User will be presented with a UI to confirm
that they want your app to have permission to access this API. In the event that
initial permission has been revoked, or disabled you will be given a negative boolean
value.
</div><br />
<h4>Select an authenticated ACAccount</h4><script src=
"https://gist.github.com/3752849.js" type="text/javascript">
</script>
<div>
Your block will need to reference your <em>ACAccountStore</em> instance in order to
see which accounts you have access to. To actually access the accounts you need to
call the <em>accountsWithAccountType:</em> method which returns a <i>NSArray</i> of
<i>ACAccount</i> objects. Where the type argument is account type we got in the
previous section.<br />
Apple has designed the <em>ACAccountStore</em> class to support
multiple authorised user accounts. While iOS 6 only supports a single
Facebook account, it does support multiple Twitter accounts. So while it is safe to
assume that first (and only entry) in this collection is the <i>ACAccount</i> you
want to use, the same cannot be said when you are working with Twitter accounts.
Ideally you would want to present a 'picker' UI to the end user.
</div><br />
<h4>Construct a SLRequest</h4><script src="https://gist.github.com/3752600.js" type=
"text/javascript">
</script>
<div>
<i>SLRequest</i> is the Social frameworks <i>NSURL</i> request abstraction to enable
it to support request signing, and token passing, features used by Twitter and
Facebook. The <i>SLRequest</i> class also has a convenience method for dispatching
this request.
</div>
<div>
If you are a fan of request queuing, and application wide request management there is
also the option to extract a prepared <em>NSURLRequest</em> object with you can then
pass to something like an AFNetworking request operation (See below).
</div><script src="https://gist.github.com/3752864.js" type="text/javascript">
</script><br />
<div>
<br />
That's it! If you weren't able to string the process together in your head magically,
you can view the entire <a href="https://gist.github.com/3752113">gist</a>. Thanks
for reading!
</div>Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0San Francisco, CA, USA37.7749295 -122.419415537.6745235 -122.577344 37.8753355 -122.261487tag:blogger.com,1999:blog-12539200.post-44591188748735371042012-06-19T21:36:00.000+01:002012-06-19T21:36:19.509+01:00Parse + CocoaLumberJack = Remote loggingI love logs, they're just so useful. Usually when i want to do some logging i save the data to a CSV file using my <a href="https://github.com/veritech/FRCSVFormatter">FRCSVFormatter</a>. However, i've been wanting to try out <a href="http://parse.com/">Parse</a> for quite some time, so it was mash up time.<div>
<br /></div>
<div>
<a href="https://github.com/robbiehanson/CocoaLumberjack">CocoaLumberJack</a> is probably my favourite logging framework. Thanks to it's modular nature you can easily create your own log formatters, or in this case create your own loggers. What i've done is implement a Parse "objects"inside of a <i>DDAbstractLogger</i> subclass which enables this ...</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-c-tLISsYeN872fHdpf9fBKcSC0KCf77i2cIhyh6FLmS0bZLgSO8ONzl2PAwNi5S0ZAqJw9il8QsDeSUqxUxZRfbwfZIuXbak_Unc0XaaWXjrgzmJ29_MPnZYD9zhCZzn9cLe/s1600/Screen+Shot+2012-06-19+at+15.14.11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-c-tLISsYeN872fHdpf9fBKcSC0KCf77i2cIhyh6FLmS0bZLgSO8ONzl2PAwNi5S0ZAqJw9il8QsDeSUqxUxZRfbwfZIuXbak_Unc0XaaWXjrgzmJ29_MPnZYD9zhCZzn9cLe/s640/Screen+Shot+2012-06-19+at+15.14.11.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<div>
I've added in the <i>[[UIDevice currentDevice] name] </i>so that you can differentiate between the devices. You could also sort my messages, method name, file name and line number.</div>
<div>
<br /></div>
<div>
Check it out on <a href="https://github.com/veritech/FRParseLogger">Github</a></div>Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0tag:blogger.com,1999:blog-12539200.post-59386033558786109092012-05-16T05:25:00.002+01:002012-05-16T05:25:53.200+01:00Around the sun and back againOne year on the road, and through almost zero planning i've ended up in the place that i've started, retracing a route that i previously travelled.<br />
<br />
I coined a new phrase today, "My impressions of so much, are coloured by my knowledge of so little". It would appear that i have more to learn.Anonymoushttp://www.blogger.com/profile/15149035779556934188noreply@blogger.com0