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.
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!
Sunday, September 23, 2012
The evolution of lazy initialization
In the beginning
The ARC evolution
Clang takes it up a notch
Option 1.
- Public readonly property declaration
- Private readwrite property (re)declaration in a class extension
- Assign our instance to the ivar
Option 2.
Whats the solution?
Wednesday, September 07, 2011
Making UIImages with blocks
So i made it awesome, and as everyone knows to make your code awesome you add some blocks to it.
My problem was simple, i was faced with the need to create two CGBitmapContext, for the uniformed the following code is required to prepare a bitmap context for drawing.
So after a bit of thought, i decided what i really wanted was a method that did all of this for me, and meant that i didn't have to worry about constantly checking the code for leaks (DRY), and that was pleasant to look at and i came up with the above. The block that you pass in is given a fully formed CGBitmapContext, and the method returns a UIImage generated from that context. Almost like a UIView/CALayer.
So now your thinking, "Yeah, thats cool, but why the [INSERT FOUR LETTER WORD] would i want to use it ?" Well young grasshopper, have you ever wanted to mask a image in code? You know to do those trendy rounded corners ... well yes you can use CALayer's however the idea of using those off the main thread makes me uneasy, and we all know the cool kids do things in the background.
The above actually creates a rounded rect on the fly, and masks the image with it. It's made to be used in a category on UIImage. But look closer, yep thats right kids, no boiler plate, ZERO, NADA, 另, SQUAT (i think you get the point)!
I should take a moment to mention that the awesome code for the rounded rect comes from the awesome Oliver Drobnik, i have the utmost respect for this guy, not just for this snippet, but if you've ever seen his Rich text label and it's associated projects, you'll understand why real soon.
Saturday, July 30, 2011
Auto incrementing version numbers in Xcode
I don't think anyone actually enjoys editing a plists, whether its in Xcode plist editor or the down and dirty XML. So has a result it was the perfect opportunity to get familiar with xcode's build process, and how to tie external scripts into it.
I use 3 segment version numbers (1.1.1), where the first digit is the major version, second digit is the minor version, and the 3rd digit is the build. For the benefit of the team, i wanted to have the latest commit hash in the build number so that people could quickly reference it and know whats going on.
With some direction from this post by Duane Sibilly i was able to hack together the below.
Tuesday, April 12, 2011
Animating a series of images with CALayer
So you want a to animate a series of images, flip book style. While it is true you can use UIImageView, everyone knows that is for wimps. Real men (& ladies ;) ) use CALayer (like a boss)...
But how? Well you might have some how got in your head that CALayer's contents property supports a NSArray of CGImages. Well this is not the answer, remember that the contents property takes an 'id'as a argument so it supports virtually everything under the sun and then some. Hell, if you felt like making crazy things happen you could just throw a NSData object in there.
Anyways, the actual solution is to use a CAKeyFrameAnimation, to manage the rotation of your images, control the frame rate, and ultimately the duration.
Well all is said and done it should look at this
Thursday, February 10, 2011
Creating Push Notification certificates that you can use .cert -> .pem
To further aid this, threw together a little shell script that takes two arguements, the certificate.p12 file and the private key.p12 file and creates a apns_certificate.pem file. Saves a bit of typing and also gives you a hard copy of the commands needed to create the certificates
Friday, January 14, 2011
Tuesday, January 04, 2011
NSNotificationQueue, Coalescing and SIGABRT
I've come to love many cocoa API's over the last year. One i've been late to embrace is NSNotificationQueue. What can i say that hasn't already been made clear ... it's a queue for notification objects ... well almost it has one particular feature that makes it totally awesome, Coalescing.
Coalescing is useful for when you want to call a method multiple times but only have it execute it's action once every so often. Since i've started coding for iOS i've been a fan of simply calling [UITableView reloadData] to refresh my table views, it's simple concise and i don't have to worry about index paths etc. However if you are drawing complex cells, and you need to call this method while you process some data you really don't want to happen every single time, the user isn't playing COD, they just want to see their data, and not have it flick around. So in my UITableViewDataSource classes i do this ...
With the handler to the reloadNotification calling the actual reload method. This means that in one area of my app, where i am listening for NSManagedObjectContextObjectsDidChangeNotification (gotta love cocoa conciseness )the reload method gets called just once instead of 10+ times.
Awesome right ....
Well there is a problem, you might have noticed that enqueueNotification: takes a postingStyle. This calculates when in the duration of the run loop the queue will attempt to deliver your notification. Because i want my Run loop to be a free spirit and not care about what my crazy background threads were doing i would usually choose NSPostWhenIdle. Well i did till today.
The problem is the UITableView that this data source is assigned to can be dealloc'd at anytime, and while my dataSource is a good cocoa citizen and removes it's self as an observer before it is dealloc'd the notification has already been assigned it's target and is waiting till the run loop is idle ... read waiting till after my object has been dealloc'd. This of course means the the objective-c runtime attempts to call the reload method on dealloc'd object, and we all know what happens when that happens ... Well i thought i did. I code with NSZombieEnabled on, so in such a situation i expect to see a nice friendly message saying i've sent a message to an invalid object ... I got that message ... sometimes. Instead 9/10 times i got a big, fat, bold SIGABRT.
Oh, but you have stack traces ... um no. When crap happens in the objective-c runtime, you close your eyes and pray that they will go away, well thats what i do.
Anyways the solution was to ensure that notification was dispatched as quickly as possible, so NSPostNow was a much better fit. My professional($_$) opinion is that unless you have a long running object (ie the app delegate) or a singleton, never use the NSPostWhenIdle.
Conclusion
NSPostNow > NSPostWhenIdle
(9 out of 10 times)
Sunday, September 05, 2010
DONT BUY CHEAP SSL CERTIFICATES FROM GODADDY!! [Updated]
Well looks like i was wrong. The actual problem was that the intermediate certificate had not been installed on the remote server. Sorry, Go Daddy. I would like to thank vincent who suggested this, and the GoDaddy representative on twitter @godaddy.
In my defense (Read: covering my ass) i didn't setup up the server, so i assumed that it had been done correctly.
On the upside it's working now :)
Synopsis
Don't buy cheap SSL certificates from GoDaddy if you plan to use them with the iPhone (read DON'T BUY THEM EVA). GoDaddy doesn't use a Root Certificate Authority that is validated by iOS.
How i found this out
For my latest iOS app i was working with in collaboration with some other developers that were building the server backend for the app. Like all good programmers we agreed that communications between the devices and the remote servers should be performed over SSL.
After shipping a beta to my clients, the backend team reported that they didn't have any traces of my app in their server logs. This was strange as i was using my favourite ASIHTTPRequest library. I've used it countless times, so i was fairly sure that i wasn't making a mistake, but logs don't lie.
When stuff like this happens, my first instinct is to grab wireshark, and see whats happening on the wire. Now any 12 year old hacker will tell that you can't sniff SSL traffic, so i made my requests over plain old HTTP. I confirmed that the requests reached the server, were processed and a 200 response was returned. I reported my findings to the backend team, and shipped them a new beta with logging enabled so they could see that i wasn't a complete retard...
And this is where if got strange, they responded that they saw my application report the requests and their failure, but stranger still their log messages where blank. Usually an Apache log entry contains the URL requested, along with a user agent, not this time, there was only a timestamp. After enabling Debug mode on the server, it reported that the connection had been aborted partway through the SSL handshake (1st Clue)
With that obvious clue, i completely ignored that, and used NSURLConnection to make my request instead of ASIHTTPRequest. However my requests over SSL where still failing, returning a nil NSURLResponse object.
The answer (as always) lay embedded in the [NSError localizedDescription]
The certificate for this server is invalid. You might be connecting to a server that is pretending to be “REDACTED.com” which could put your confidential information at risk., NSUnderlyingError=0x2f8c30
So i checked the certificate ... It was of course valid for another year. Ok that was weird. So i googled the error number "NSURLError 1202". It led me to a page on the Facebook developer forums
This error code is know in the iOS world as
NSURLErrorServerCertificateUntrusted
On the page, they mention the phase "trusted root certificate authority", something that i've learnt about from Steve Gibson & Leo Laporte on Security Now.
So i decided to find out the name of the servers root authority, it was a company called valicert.com.
The great folks (you guys better approve this app!!) at Apple have published a list of trusted root certificates and guess what ladies and gents (Drum roll) valicert.com is not there.
Sure enough visiting the URL in the browser presented me a dialog asking me if i wanted to proceed with a untrusted certificate. Now while i can press yes, any user using my application would have to do the same thing, Not a good user experience anyway you swing it. Hence the headline. The solution is to splash the cash, and use a more widely recognised authority.
On the flip side this is a massive win for Apple, as it means you gotta use most of the money (that you don't share with me) you've been stealing from peoples accounts using that botnet to purchase your certificate, and fake business address. But seriously hats off to Apple, this should help keep the amount of spoofing on the iPhone to a minimum, well if they fix all the buffer overflows first ...
Hopefully i've saved someones nightmare.
Jonathan
Thursday, August 12, 2010
So i got bored and made a web app part one
I also looked at lighthouse app and some of the others and thought to myself, these are relatively expensive for what i need, plus i can see this scaling to a large number of users in short order.
And lets not forget most importantly i wanted to stroke my own ego ...
My goals are to make a simple tracking app, with support for multiple projects and maybe even some github support :) Also i want to play around with CakePHP's ARO support for Happy Not Happy, so it's a double edge sword.
Monday, July 26, 2010
Application wide Fonts
So as an example you could create a category on UILabel, and create a class method called labelWithAppSettings. This method would do the following
- Allocate and instantiate a UILabel
- Set it's font using one of the methods from UIFont+Additions
- Return a Autoreleased object
Thursday, July 22, 2010
Getting Annoyed so you don't have too
Happy coding
Sunday, March 28, 2010
Mocking Core Location
This is fresh out of the oven, i plan to add a timer and exec the sendUpdate method after a set delay and read the locations from a text file. I'll post it up on git hub if i ever get it done
Update 29/03/10
Since writing this post i've put up a working version of the code on GitHub, Fork away
Monday, March 22, 2010
SVG Graphics on the iPhone
Yeah, that performance sucks.
My problem is two fold, my client wants to export the data as a vector. Common sense wil tell you, that importing multiple vectors and then trying to export them again as a vector, in raster/bitmap based container isn't going to work.
So it looks like me and the SVG spec are going to get really cosy. The only blessing here is that SVG's that my client wants to use are fairly simple, so i should need to implement the entire spec.
Sunday, March 21, 2010
Non Global Singletons in Obj-C
Generally speaking, Cocoa coventions (at least in all the documentation i've read), recommendation for sharing object instances across multiple controllers is to make it part of the application delegate. Personally i hate this, as it leads to a congested app delegate full of random iVars. Now it could be argued that if you find yourself in this place your doing it wrong, and in all truth you probably are. But considering that apple themselves suggest placing the CoreData ObjectContext in the app delegate, i think we're in good company.
My solution takes advantage of one of objective-c's many unique features, categories. Categories allow you to add methods to a class without modifing or subclassing. To most non cocoa programmers i just blew your mind, just wait to you find out about Swizzling!
Essentially i define a category on the class that i want to use as a singleton. In my scenario i wanted to have a single CLLocationManager In my entire app. This is because i need to access the devices location on a regular basis, and i want a global accuracy configuration ... and i just wanna try out some stuff :).
Code time
What i have done is simulated the typical method that you would expect to see for a singleton instance, but behind the scenes this method calls a property on the app delegate to get the shared instance variable.
In my eyes the positives to this approach are:
No global variable for the instance.
The Share instance is where you would expect it to me, and if required can be serialized on app exit.
Accessing the instance is as easy as [CLLocationManager sharedInstance] vs [[[[UIApplication sharedApplication] delegate] locationManager]
Lastly, if the internets tell me that this is a wacky idea i can refractor this to classic singleton, without making mass changes to my app. Thoughts and opinions.
Monday, February 22, 2010
CakePHP & User Uploads
Thankfully cakes media views allow you to specify a folder anywhere on the webserver!
What i decided to do was to make a simple controller called media and route all of my USG images through it.
class MediaController extends AppController {
/**
*
* @var string
* @access public
*/
var $name = 'Media';
var $uses = array();
/**
* Index action.
*
* @access public
*/
function index( $file = null, $size = 's' ) {
$this->view = 'Media';
$components = split('\.',$file);
$params = array(
'id'=> $components[0],
'name'=> $components[0],
'extension'=> $components[1],
'path' => ROOT . DS. 'media' . DS .'filter'. DS . $size .DS . 'transfer' . DS . 'gen' . DS
);
$this->set($params);
}
}
So the controller looks a little something like this in it's raw form. I'm using the Media plugin, hence the addition folder paths. The key thing to note is the 'Path' key/val pair in the $params array. Notice you can pass an absolute file path! so in theory you could even mount another drive, and serve your media from there, pretty awesome.
This way, i can use a url like this
example.com/media/filename.jpg/l
To get a large image, and
example.com/media/filename.jpg/s
And this to get a small image.
Quite handy!
Monday, May 19, 2008
Backrow, Thats a big ass framework
The main sticking point for me has been the lack of documenation, however this should be expected considering that we're talking about a unsupported framework, from one of the most secretive corporate entities in existance.
So in my quest to write for leopard front row, i decided that a nice class diagram would come in handy, easy right...

Well this is what it looks like, after exploring appoximately 30-40% of the 500+ classes!
However i've learnt alot about naming conventions and framework layout. The most striking thing is the level of depth. For example there are classes for everything under the sun, like the Entry of IPv6 addresses. Stuff i personally would have overlooked. I guess thats why i get the semi-big bucks.
Needless to say the folks at apple know how to design a framework, and have done a great job in the absence of namespaces, to provide rigid catagorization of classes.
Class names are nice and logical, for example any class ending with 'layer', is most likely a subclass of BRRenderLayer, eg. BRListLayer or BRTextMenuLayer.
The experience has also made me feel like i've been using the framework, rather than an outsider, looking in. So hopefully in the coming days i can actually leverage this thing to do something other than allow me navigate tv series from the comfort of my bed.
Quote of the Day
"It's a pitty they made so much fuss about gay cowboys, it's actually a decent film"
I happen to think brokeback mountain is a half decent flick
Sunday, January 27, 2008
When it rains it php's
Introducing the super dupa know it all function, should be good for PHP 4+
PHP
/*
Make a camel case string user friendly ^_^
*/
function implodeCamelCase( $pStr, $delimiter = ' '){
$strArr = str_split($pStr);
$retArr = array();
foreach( $strArr as $val ){
if( ord($val) <= 90 ){
array_push($retArr, ' ');
}
//add to return array
array_push($retArr, $val);
}
//explictly destroy array
$strArr = null;
return mb_convert_case(implode('',$retArr),MB_CASE_TITLE);
}
It's a bit rough around the edges, anything thats not a lower case character or anything else with a decimal ascii number over 90, will have a space inserted before it, of course thats easy enough to tweak.
Wednesday, January 09, 2008
Happy New year, have a server for 08
I'm in the middle of finishing up my Object Orientated Application Assignment, and i ran across this piece of code in my repository.
import java.io.*;
import java.net.*;
public class ServerInstance {
private Socket Connection;
private BufferedOutputStream Outbound;
private InputStream Inbound;
private HTTPData RawHttpData;
private int listeningPort;
//ClassFlags
private boolean connectionEstablished = false;
private boolean instanceComplete = false;
public ServerInstance(){
//This one Sets all variables to defaults
listeningPort = Preferences.DEFAULTPORT;
}
/*public ServerInstance(Preferences){
}*/
public boolean run(){
ServerSocket ListenSocket;
boolean retBool = false;
boolean endLoop = false;
int readValue = -1024; // Set to extreme value to show that it is default;
int i = 0;
/*
* How the Server Will work
*
* 1. Get the Data from the browser / Read the Stream
* 2. Send Data off to extract the headers
* 3. While Data is being Processed Send data back to the client
* 4. Flag that server action is complete, and shutdown and clean up
*
*/
try{
ListeningSocket = new ServerSocket( listeningPort );
Connection = ListeningSocket.accept();
connectionEstablished = true;
//1. Get Data from Browser
Inbound = Connection.getInputStream();
Outbound = new BufferedOutputStream ( Connection.getOutputStream() ); //Place output in a Buffered Stream
//Write to both Objects simultainously
while( !endLoop ){
readValue = Inbound.read();
if(readValue != -1){
Outbound.write( readValue ); //Send data to the client
RawHttpData.write( readValue ); //Write data to a HTTPData Object
}
else{
endLoop = true;
}
i++;
}
Outbound.flush(); //Make sure all the data has been sent back to the browser
//Just while we code
System.out.println("Server: has RX/TX " + i + " Bytes of data");
//4. Clean up
Inbound.close();
Outbound.close();
Connection.close();
instanceComplete = true;
}
catch(IOException e){
System.out.println("<-- Server Error -->");
System.err.print( e );
}
catch(IllegalBlockingModeException e){
//I doubt this will come up, but refer to java documentation on serversocket.accept() in the event it does
System.out.println("<-- Server says no! -->");
System.err.print( e );
}
finally{
return retBool;
}
}
public boolean isConnected(){
return connectionEstablished;
}
public boolean isComplete(){
return instanceComplete;
}
}
Code is released under the GPL 2.0 License, go forth and improve (and credit).
This is a working server implementation in java, a relic from my isolation project,( Isolation was meant to act as a personal proxy, similar to how google gears works, however their wouldn't need to modification to the web app, as isolation was meant to pre-fetch the data, based on monitor the users actions/http requests.).
Anyway as you can imagine this was a big project, coupled with my second major data disaster, it didn't really ever see the light of day.
Couple of things to mention, the Preferences class was a data structure to store, ... well user preferences, and the class was meant to implement the runnable interface, so that you could operate multiple server instances.
I learnt a lot researching for it, and thanks to it i have a very good idea of how the HTTP protocol works, however i think it was a little too complex for someone at my current level, i should really stick to trying to reverse engineer front row, and learning lisp.
On the note of the reversing of front row, a plugin called sapphire was released last year. From what i can determine they have worked out how to beat apples protection scheme governing the loading of foreign NSbundles (Yeah, i know about them!). So when i finally get around to it, i'll (try to) reverse it as well.
Quote of the Day
"Rave for business"
I love Capitalism, don't you



