So, I seem to have come full circle… let me explain:
After quitting a dayjob working for the man almost a year ago to try venturing out on my own, I’m now working at a bank 9-5. Working for the man again, if you will. It’s not so bad, really, there are some good guys I’m working with now (nerf gun fights at a bank, really?) but i’ve had a few people laugh for taking such a safe job! Well, too bad - i’ve got bills to pay! You’d do the same, wouldn’t you? Here’s hoping your road to entrepreneurship is less pot-holed than mine :)
So, speaking of bills, how’s my contracting-to-slay-my-old-builders-debt quest going? Lets see, we’re out of pocket a certain amount (email me if you’d like to discuss details!). Doing some sums for what risky contracting pays (post-tax) over what safe full-time work pays, it looks like I’m almost exactly 1/3rd of the way through that debt. So roughly 40 more weeks to go. So basically around christmas we should be OK again. I hadn’t done the sums until it was time to write this blog, i didn’t realise it would be so long. Ouch - debt hurts, especially when it’s not really your fault. Choose your builder wisely!
On the plus side, our new builder is progressing nicely. Half the brickwork is up now, it’s beginning to look more house-y. Now we have to spend hours choosing things like doors and kitchen stuff and tiles and so on. And colour schemes! I’m so worried that i’ll mess up the colours and the place will look terrible.
So, what have I been up to the last 9 weeks? Well, I’ve been contracting at a super-cool joint in Sydney called Snepo, working on an enterprise iPad app (huge market there, i had no idea), and a funnier app: Fundawear! Just look it up on Youtube (maybe not while you’re at work), I promise you’ll have a laugh. Pretty embarrasing app for a pretty-boring conservative family guy like me but what the heck sometimes you gotta do something fun. We got almost 5 million hits on youtube out of it would you believe! Anyway, thanks Ben for the opportunity to have fun with that project, you were a champ to work for :)
So I finished that book on learned optimism by seligman. He basically said you need to deliberately think on problems as temporary and not affecting all areas of your life. It was a cracker! Heck, if i can get through all this having learned how to be a more optimistic guy in general, it won’t have been an entirely wasted year. Anyway I’m going to read his later book, ‘Flourish’ soon.
Amusingly, I read another book by mistake last week: ‘Who switched off your brain’ by Dr Leaf. True story, I was meant to read her other book ‘Who switched off my brain’ as recommended by my wife - I ordered the wrong one. The ‘my brain’ book is about having healthy thought patterns, whereas the ‘your brain’ book is about marriage and the physical differences in our brains. Did you know that men have 10x the grey matter in our brains than women, and women have 6x the white matter? Fascinating, but not very useful in my quest to become more positive. Seriously, who reads a wrong book by mistake?
You may recall I hired a guy to make some artwork for a game via eLance, and was saying it was awesome. Well… he hasn’t gotten back to me in a while, I think it’s not going to happen. Oh well, it was worth a try. I’m still not going to bother making iOS productivity apps, but a mate is dead set on convincing me to make a SaaS web-app - Scott, i’ll get to it one day I promise! You write one first, make a living from it, then i’ll be super-keen!
Oh, speaking of SaaS: microconf just finished. It’s like the conference for boostrapping SaaS entrepreneurs - can’t wait till the videos are up!
So, I recorded a few screencasts on iOS development and threw them up on Youtube / Hacker News to see if anyone was interested. Looking at the youtube stats, it turns out that nobody was interested :) Well, was worth a try! I still think there’s a market for learning materials for how to make iOS apps out there somewhere. Having said that, i don’t think i’ll bother recording any more screencasts at this stage.
Anyway, all the best to all the budding entrepreneurs out there, keep clawing away at it all, have a great month or so till I write next! Please send emails, i love having a chat about all this kind of stuff :)
Do interface builder and storyboards drive you crazy? Do you like the idea of laying out out your views once, such that they get placed correctly on the ipad, iphone4, and iphone5, in both landscape and portrait modes, adjusting automatically for the height of tab and navigation bars? I think a pitfall for new iOS developers is that tutorials teach only interface builder and lot of people are never made aware that there could be an alternative. Well, there is an alternative. Keep an open mind and hear me out…
Here are a few reasons why you might want to split up with interface builder (IB). You may not have had all these problems, but i’m sure a few of these will ring true.
You may also want to skip over this section if you don’t need any more convincing that IB isn’t fantastic.
Here’s what I’ve used at my last four contracts, making properly complicated apps. It may look like a bit more work on the surface, but I can attest that it has well and truly paid off. Alright here goes:
In my apps, for each ViewController I make a ‘XXXViewController’ class. This class looks like so:
#import "MyViewController.h"
#import "MyView.h"
@implementation AreaViewController {
MyView *_myView;
}
- (id)init {
if (self = [super init]) {
// Do init-y stuff here...
}
return self;
}
- (void)loadView {
_myView = [[MyView alloc] init];
// Configure _myView...
self.view = _areaView;
}
...
The gist of the above is that by creating a MyView and setting it to self.view, it becomes the managed view of this view controller. We don’t even need to set its frame - that is taken care for us by the parent VC (typically a UINavigationController in most apps). It’s all quite neat.
Notice we’re just using ‘init’, instead of initWithNibName, too. This keeps things cleaner when actually instantiating one of these view controllers.
The corresponding MyView which is managed by the view controller looks like below:
#import "MyView.h"
#import "UIView+Helpers.h"
static int kLabelMargin = 10;
static int kLabelHeight = 44;
@implementation AreaView {
UILabel *_someLabel;
UILabel *_bottomLabel;
}
- (id)init {
if (self = [super init]) {
_someLabel = [self addLabelWithText:@"Hello"];
_bottomLabel = [self addLabelWithText:@"Goodbye"];
… create other subviews
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
int width = self.bounds.size.width;
int height = self.bounds.size.height;
_someLabel.frame = CGRectMake(kLabelMargin, kLabelMargin,
width - 2*kLabelMargin, kLabelHeight);
_bottomLabel.frame = CGRectMake(kLabelMargin,
height - kLabelMargin - kLabelHeight,
width - 2*kLabelMargin, kLabelHeight);
}
And with the above code, you’ll have two labels centred at the top and bottom of the screen respectively, with 10px margins. And even if you rotate the device to another orientation, it’ll correctly position them again at the top and bottom, with the appropriate width. This code will work for the iPad, iPhone4, and iPhone5 unchanged. And look, no magic numbers for the various screen sizes.
Also, if you position it inside a navigation controller or tab controller (or both), it’ll still get the layout correct, effortlessly, without you needing to account for the height of the navigation/tab bars.
But where did addLabelWithText come from? To make the init methods of custom views manageable, it’s best to make a category on UIView with some helper methods to create labels / image views / buttons / etc. The rule of thumb I follow is that these helpers must:
These methods are pretty simple to create, so i’ll only show one as an example:
- (UIButton *)addButtonWithImageNamed:(NSString *)name {
UIImage *image = [UIImage imageNamed:name];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:image forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0,
image.size.width, image.size.height);
[self addSubview:button];
return button;
}
So, to use the new view controller, we’d have something like below in the app delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch…
UIViewController *myVC = [[MyViewController alloc] init];
self.viewController = [UINavigationController alloc]
initWithRootViewController:myVC];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Notice that it’s a simple matter of calling alloc init, without requiring the bulky initWithNibName.
So here are some closing thoughts i’ve had for this technique.
It gives a clearer understanding of what’s actually going on and the structure of your VC hierarchy. I just feel more ‘in control’ coding this way. It is a bit slower, but I feel like it makes up for that in spending less time scratching your head over quirky layout issues etc.
Another neat trick: if you have subviews that you only want to be able to see on the iPhone 5, but hide them on the iPhone 4 because their positioning clashes with another view and they’re not critically important, you can do something like the following at the bottom of your layoutSubviews method:
_optionalView.hidden = CGRectIntersectsRect(_optionalView.frame, _importantView.frame);
Having said all this, if you end up using this technique on your more complicated screens, and stick with xib’s for your simpler screens, I’d agree that’s a reasonable compromise. Maybe just keep this technique in mind for those times that IB really starts getting in the way? Just another tool for your toolbox.
I just feel like using IB for your UI is like back in the early days of web development, when everyone was using various WYSIWYG tools (remember FrontPage, anybody?) to create HTML files, with varying degrees of success. And over the years, it became the ‘done thing’ to do your HTML by hand, in a text editor. I think, for more complicated apps at least, iOS will tend the same way.
Have a nice weekend!
Hi all, it’s been a big few weeks. I’ve been consciously trying to become a more positive guy, read a few books on the subject, our house has started getting underway again and now has a roof and some brickwork, I’m half way through my latest contract, and I’ve recorded a couple of screencasts.
I’ve also dipped my toe back in the waters of making my own apps (games). Here’s our house as it stands now:

So, in the last few weeks I’ve made a couple of screencasts on iOS development for beginners, showing how to make an app from the very first opening of Xcode. You can blame Scott - he put me up to it. But the difference (hopefully) is that these beginner screencasts would teach best practices, not ‘beginners fluff’ that hurts you in the long run. Anyway, they’re pretty rough but if you find this useful i’d love feedback, if these prove popular i’d definitely make a series of them. Here’s part 1, making a todo-list:
And here’s part 2, saving and loading data so it persists across app launches:
Note that youtube will default to playing these in 720p - be sure to click the settings icon (bottom right in the youtube player) to change these to glorious 1080p. And if you’ve got ideas for topics for further screencasts, let me know.
So last time, I spoke about trying to make an iOS game in my spare time (my current contract is part time). Well, i have to admit it’s very hard to find the time to work on games on my time off with two kids under my feet! So not much progress there.
However, i’ve been poking around on elance.com, and I’m teaming up with a guy who will do the design work with me on a game idea i’ve been wanting to do for quite a long while now, but i’ve always put it off because i thought the artwork would cost a fortune. But, from what i’ve been quoted, it seems it won’t cost very much at all.
You developers out there should take note: if you’ve got an idea for a game but haven’t made it because you can’t draw the artwork - pay someone on elance, it’s much cheaper than you think. No more excuses!
As for the year of positive thinking - well, i’ve started off by reading. I’ve read ‘How Children Succeed’ by paul tough, which i thought would be a great way to learn how to be resilient in the face of adversity. However, the book was more observational than ‘here are the lessons learned and how to put them into practice’. However, it did put me onto a much better book…
I’m currently half way through ‘Learned Optimism’ by Seligman. And it’s much more practical. Basically, he says that helplessness (the ‘my efforts make no difference’ mindset) is the enemy, and that the trick to stopping adversity leading to helplessness is to think as follows:
Anyway, i’ve put a repeating reminder on my phone to think (meditate?) on two of these thoughts daily: our house will be finished soon; and despite the financial mess, my family is all healthy. I’ll try this for a month. Maybe you should too?
This time I’ve only got one site that a mate has been working on: projectmatches.com. The idea is that freelancers spend too much time searching for jobs on clunky job boards, and this service will streamline the process for you. Go and sign up for the pre-launch list if you like the sound of it!
Anyway, all the best, hope you got something out of the screencasts if you’re a budding iOS developer, and have a great month.
Well, another month has gone by. What’s new? Firstly - my contract at Fox has finished. After a week off (in which i didn’t surf at all), I took a short, part-time contract at an agency in Sydney - it’s been two weeks so far.
As for app store entrepreneurship - well, i’m afraid i’m out of ideas here. Now that IAP has proved unsuccessful in making anything out of my calendar app, my only remaining idea is to get into games. I know, I keep talking about making a SaaS app, but the reality is that my web development skills are pretty mediocre.
So, what’s 2013 going to be all about, then? I know it’s a bit late for new-years resolutions, but what the hell… every year needs a theme. 2013, career-wise, i’ll just focus on contracting. The baby rules out spending a serious amount of time in the evenings on a side business, and i can’t spend the whole year contracting part-time, working on a business a few days a week - i simply need to work full time, to pay down the debt on our home. So - career is not really going to be a focus this year.
One thing, though, that has been grabbing my attention lately is character in general, and positivity specifically. I’ve come to the conclusion that i need to become a positive/resilient person. Too much negativity has done me no favours, and it needs to stop - this year i’m going to have a crack at beating it.
I’ve been reading ‘How Children Succeed’ over the last week, and it talks about character qualities needed to succeed, such as: grit, self-control, zest, social intelligence, gratitude, optimism, curiosity, resourcefulness, resilience, ambition, professionalism, and integrity. Overall, these all make up good character. But i’m just going to focus on one: optimism (aka positivity).
Here’s the idea: becoming more optimistic will lead to being more resilient, reduce catastrophising, and deal with those depressed pity-parties we all have from time to time, especially us developers (i know what we’re all like!). The only problem is that i’m not sure how to become optimistic… i’ll start by talking to some close friends. Anyway, it’s worth a shot? I’ve got some crazy idea about how the world needs a ‘khan academy’ for lessons on positivity and character, but i think it’s just a crazy idea.
For the next month or two, i’ll be working part-time. Which leaves me thinking - what project can i work on part-time for only a couple months? I certainly can’t afford to work full-time all year, so my next contract will be full-time, so i need a project that’ll take about 12 days to complete. Maybe an iOS game?
I’ve been playing the game ‘Radiant’ on iOS lately. Lots of fun. Basically a space invaders clone, but with pretty neat glowing/retro/pixelated graphics. And then I saw their public sales numbers on Google Play: the range shown is 10-50k sales per month. That’s somewhere between 240k/year and 1.2M of revenue. And i can only assume that on iOS it’s higher. For an asteroids clone! Wow!
So i started experimenting, and found that I could replicate the graphics effects in code. So my idea is to spend my days off making a remake of a retro game, in a graphical style inspired by Radiant. I was thinking centipede or something action-y.
Good news! Our new builder started this week on our house. Carpenters are carpenting, port-a-loo’s are going up, roofing is soon to be installed, bricks are being delivered, terribly exciting. Except that now i’ve got bills to pay!
One more thing: Google is discontinuing Reader. So if you subscribe to my blog via RSS, maybe you should consider signing up to my email list instead now? The sign-up is at the top of my blog here!
Finally! I’ve got some stories of projects you guys are working on :)
Firstly, Sean Carpenter and his wife started a business doing web and app development. Here’s their first app’s description:
Menstruation Calendar Period! helps you keep track of your menstruation start days and lets you know when to expect your next period. It is simple to use, has no extra data to enter, and no annoying pop-ups. If you simply want to plan around your period and know when your period is late, this is the app for you!
Next, a mate has released the third chapter to his BeBee the Bee kids ipad game, extremely cool.
And finally, a guy called Joao has been working on a SaaS app with an iPhone companion app called Yodito. Sounds like exactly the business model I should be pursuing, right? Anyway, check it out.
Have a great week, all, and keep pursuing your dreams!
So I thought i’d write a regular series of blog posts on where iOS development is at, every 6 months say. Kind of like how the americans have their ‘state of the union’ address every now and again. Plus, I can’t sleep tonight - the stress of contracting is getting to me again. So here goes the first one, as of early 2013. Please keep in mind that this is entirely subjective and my opinions so take it all with a grain of salt!
What follows is a rough description of how I create and lay out views in my view controllers these days, a method which I’ve seen a lot of senior devs use as well. It helps me handle the giraffe(5) vs stubby(4) iPhone sizes easily, and handle screen rotations on the iPad easily too. You’ll notice that xib’s aren’t featured here: I haven’t met many people who use or like them any more.
The first case is where your view controller only has one view: usually a UITableView or a UICollectionView. In this case, in your VC’s loadView, you do something like this:
- (void)loadView {
self.view = [[UISomethingView alloc] init];
}
Note that you’re not specifying the frame size of the view - since this view is now managed by the VC, it is the container VC’s responsibility to size it for you to fill the appropriate space. So you don’t need any layout code in the VC at all. Also, careful not to call [super loadView] here, or it’ll create a default empty view as the VC’s main view.
A common situation is to have a view controller with a table or collection view, a loading view, and maybe a search box. In this case, none of those three views can be assigned as the VC’s main view, they all have to be added as subviews. But because there are only a few of them, it’s not worth creating a custom UIView subclass to manage them. So here’s what I do:
- (void)viewDidLoad {
[super viewDidLoad];
_myTableView = [[UITableView alloc] initWithFrame:CGRectZero
style:UITableViewStylePlain]];
_someOtherView = [[UIView alloc] init];
.. make your loading / search box views here ..
[self.view addSubView:_myTableView]
}
Notice that i’m not specifying the view frames yet. Where possible, i just call the ‘init’ without a frame for brevity, and since UITableView needs a frame for its designated initialiser, i just pass CGRectZero. The reason for this is that these views are to be laid out below:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
int width = self.view.bounds.size.width;
int height = self.view.bounds.size.height;
_myTableView.frame = self.view.bounds; // Fill the whole area.
_myViewAtTheBottom.frame = CGRectMake(0, height-20, width, 20);
_myLoadingView.frame = .. something using the height and width ..
}
This way, you can lay out your frames using maths as complicated as you like. Just please don’t hardcode 320 or 480 anywhere, just make it all dependent on the size of the VC’s view. Also notice you don’t need to use autoresizing masks at all if you use this method. If you simply base everything off your width and height, your VC will automatically just work on a tall or short iPhone with no further code.
Say you’ve got a VC that has a dozen subviews, you’ll want to make the effort to make a custom UIView subclass to contain all those. In your VC, it’ll be a simple matter of creating one of these to be the VC’s main view:
- (void)loadView {
self.view = [[MyCustomView alloc] init];
}
You then won’t need any more layout code in your VC - which makes for really nice proper separation of concerns. In your custom view, you create all your views in your init with zero frames, and lay them out in your layoutSubviews:
- (id)init {
if (self = [super init]) {
_someSubview = [[UILabel alloc] init];
_anotherSubview = [[UIView alloc] init];
.. lots of subviews ..
[self addSubView:_someSubview];
[self addSubView:_anotherSubview];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
int width = self.bounds.size.width;
int height = self.bounds.size.height;
_myTableView.frame = self.bounds; // Fill the whole area.
_myViewAtTheBottom.frame = CGRectMake(0, height-20, width, 20);
_myLoadingView.frame = .. something using the height and width ..
}
Again, if you keep it simple like this, your VC will remain simple and clean and devoid of creation and layout of views - let your custom UIView subclass handle all that. And the only place where layout is handled is in the layoutSubviews.
As for passing information down from the VC to the labels etc in your custom view, you have two options: you can either expose the labels as properties and let the VC set the text property itself, or you can expose a setter in the custom view that takes a model object, and takes the fields from that model object and applies them to the custom labels. I’d go the latter route if there’s more than a few labels involved.
OCMock isn’t popular any more - it’s been stale for a while now, and has been missing lots of conveniences that other testing frameworks give us (such as the ability to specify a wildcard on value types in expectations). Which is a pity, I miss its bulletproof reliability - it never did anything weird, it just worked reliably.
Everyone seems to be using Kiwi for their testing now. The syntax is much nicer than OCMock, it handles all the important things for you (such as launching the simulator etc), it is much more expressive (eg you can set expectations on a non-mock object, which I think is just some kind of black magic), handles async testing reasonably well, and seems quite well rounded as a one-stop-shop testing toolbox.
That’s not to say Kiwi is perfect: the number of times i’ve had kiwi crash on me because a test failed, with no hint to be found in the stack trace of which failing test actually caused the crash, let’s just say it’s a large number. Also, i’ve often had async tests fail expectations later on during the running of another unrelated test, which makes it really difficult to figure out which test is actually failing. So it seems to be a little buggy. But when it works, it’s quite nice and slick - writing tests is much less of a chore. I think that there may be room for a more bulletproof testing framework in future, however.
As for UI/Integration testing (testing frameworks that simulate a user tapping their way through the app), KIF seems to be losing ground to Frank. However I’m of the opinion that UI testing as a whole is falling by the wayside: nobody really has the time to maintain fragile UI tests, and the benefit they give over a good set of Kiwi tests is debatable. I’ve yet to see a good set of UI tests - you may be better off sticking to Kiwi / unit tests, unless you’ve got the budget for a full-time test engineer to write these tests and keep them running.
Well, iOS5 is now old hat, and everyone seems to be targeting it now for their apps. Which is great - we can all now embrace ARC finally. Seriously, if you’re doing manual memory management still, you’re really missing out.
One key thing iOS5 gave us was over-the-air updates, which means that new versions get upgraded much more quickly than before. Which leads me to iOS6 - it hasn’t been out long, yet has a pretty large share of the market already, and you could justify targeting it for a lot of your iPhone apps these days.
iOS6 gives you much better view/layer memory management, which means we don’t need to worry about unloading views anymore - your VC just got a whole lot simpler! Unfortunately, until Google releases their maps for the iPad, i don’t think iPad developers will be able to target iOS6 - i suspect that a lot of users are holding back upgrading until they can get their beloved google maps on their ipad. I don’t blame them. But it’s a shame, because the best thing iOS6 gave iPad developers is the UICollectionView…
The collection view is the ipad’s version of the table view, in a nutshell. Expandable in every which way to take advantage of the extra screen real estate, so you can now make grid views, TV guides, horizontal or vertical scrolling tables with gaps between the cells, custom layouts, and all that good stuff with automatic cell recycling. Very handy - you need to learn it, although it does limit you to iOS6.
I’ve yet to meet anyone who has made serious money from the App Store as an indie developer making apps in their spare time. Most devs i know make a living from contracting or working full-time for a company. I think iOS6’s new app store layout has cemented that even further, now that you can only see one app at a time when browsing - it has brought more attention to the popular apps at the expense of the long tail. So don’t expect to make a living from apps any more, it’s become more of a ‘hits’ ecosystem, with no support for the long tail. I’d love to be proven wrong, of course, because i’ve got a dozen or more apps of my own in the app store, languishing in the ‘long tail’ where users no longer venture.
Thanks for reading! Now i’m off to bed…
Another year and I’m still here! If you’re wondering why I haven’t blogged in a while, well actually I have - but it’s a long story which I won’t go into here.
Anyway, last time I wrote an app-business post I spoke about giving in-app-purchases (IAPs) a try. So I converted my Today Calendar app to be free with ads, with an option to do a 99c IAP to remove the ads. Which was interesting, so i’ll share the results here. To make it more readable, i’ll give you a tongue-in-cheek weekly summary first:
And here are the actual figures if you’re interested:
Dec 20th: 700 free downloads, 12 IAPs
21st: 600 free, 2 iap (terrible!)
22nd: 650 free / 9 iap (looking good again)
23rd: 700/9
24th: 600/12
25: 580/4
26: 1101/10
27: 736/10
29: 600/7
30: 830/9
31: 610/6
1st jan: 840/12 (still looking good!)
2: 870/10
3: 710/6
4: 670/6
5: 640/7
6: 670/3
7: 388/4
8: 460/7
9: 161/4 (downloads *really* dropped off, unsure why?)
10: 120/1 (yuck)
11: 120/1 (ouch)
12: 130/4 (picking up again?)
13: 130/4
14th jan: 130 free, zero IAPs. My app is now as dead as a can of spam.
So it certainly worked better than when I was simply selling the app for $1 on the app store. I guess that’s because people have the chance to ‘test drive’ the app first before buying it, because 99c is such a huge commitment. But after a few short weeks, sales have dried up.
At least I can say i’ve tried the ads and the IAP model now. But what else remains to try? Make yet another farmville clone game? Spend megabucks on marketing? I think i’ll stick to my dayjob from now on.
One more thought before I move on, let’s look at conversion rates: on my best day, my conversion rates are about 2%, and on the worst day, about 1%. For an app with good reviews (lets be honest, not great reviews, but it’s a far cry from a one-star-wonder) - that’s just a poor reflection of the app market. About one or two in a hundred people who go to the effort of downloading my app bother shelling out a lousy buck to support the developer, ensure future updates, and nuke the nasty ads? Wow. And I’ve heard developers say ‘don’t make apps for android, the users are too tightwad to pay’, well it looks like iPhone owners aren’t any better, unfortunately.
Well! Excitingly, 2012 is over. If you’ve followed my blog, you’d know that that is excellent news. But i thought i’d write a few of the lessons I learned in 2012. You don’t have to read these if you don’t want, i’m writing these mostly for my own benefit:
I heard this week from a great guy in china who said he read an old one of my blog posts, and it inspired him to quit his job to become an iOS developer! How cool is that. Well, if anyone else is feeling the need to change jobs, here’s a tip: iOS contracting is great - if you want to know why, email me :)
Oh and as always, please email me if you’ve made an iOS / web app, i’d love to promote you in my next newsletter!
You can read more of my blog here in my blog archive.

(Comp Sci, Hons - UTS)
iOS Contractor / Freelancer.
I have worked at places such as Google, Fox Sports, NineMSN, FetchTV, Woolworths, among others. If you're looking for a good iOS developer, drop me a line!
Get in touch:
chris.hulbert@gmail.com
github.com/chrishulbert
my resume