iOS First Impressions

Events have conspired against me and I find myself writing an iOS app. Off the back of some relatively complete android work, I was interested to see how the platform compared.

First steps

After the gigantic pain of upgrading a dual boot Leopard/Ubuntu macbook to Mountain Lion, installing XCode was relatively trivial (albeit I had to enter my password roughly five or six hundred more times than I’d hoped). I dived straight in hoping I would soon emerge with some useful knowledge; you will have to be the judge. Onward!

Objective C isn’t actually that weird

Once you figure out that Objective-C is seriously old (possibly even as old as C++ !), some of its idiosyncrasies start to seem a little less odd.

Boolean is YES | NO

One assumes because originally, this was a macro based implementation (C doesn’t have a boolean type; or, at least, it didn’t until C99, where a standard macro implementation appeared, I think). This stackoverflow answer adds some colour.

There are no constructors 🙁

…and this has lead to a great disturbance in the force, with two idiomatic initialization methods.

  • alloc then init

[[NDHSomeType alloc] initWithParams:params]

which is tidy, but bad luck if you forget the init.

  • class methods that wrap this up for you

+(NDHSomeType *) initWithParams:(NDHParams *)params

which is tidier still, but cannot actually prevent someone still doing

[NDHSomeType alloc] 🙁

This is very annoying as it hampers our ability to create truly immutable objects.

There are no namespaces

As such, XCode forces you to pick a three letter prefix for all of your class names. For shame.

Implementation hiding is a feature

This is probably my favourite thing so far. Given a Foo.h that contains

@interface Foo
@property NSString * bar;
@end

One can, in the implementation file, Foo.m , add further functions and properties as necessary, which are hidden from calling clients, thus:

@interface Foo()
@property NSString * hiddenFromClientsButVisibleInFoo
@end

This reminds me of the well used C++ pImpl idiom (see this post for a simple example), which I’m a big fan of; as such I’m pleased this exists in objective C too!

id

This appears to be the objective C equivalent of void * . Objective C is not that type friendly – collections are not generic, and calling any method you like on an id is only a compiler warning, not an error.

That said, one can, in a function definition, suggest that the actual object that is eventually passed adhere to one or more “protocols”, thus:

@protocol NDHStringListener
-(void) onString:(NSString *) someString
@end

@interface NDHStringTransmitter
-(void) transmitString:(NSString *) someString
        toListener:(id<NDHStringListener>) listener;
@end

Now we just need a class that adheres to this protocol:

@interface NDHStringDisplayer : NSObject<NDHStringListener>
@end

Passing instances of NDHStringDisplayer to NDHStringTransmitter is now fine. Annoyingly, passing instances of objects that don’t declare protocol adherence is still only a warning; although I assume one can configure the build process to make it an error.

Blocks

This is how objective C deals with anonymous functions. The documentation covers how this works, but essentially, things aren’t too bad; blocks are not too dissimilar from C++11’s lambda.

int (^addOne)(int someInt) = ^{
    return 1 + someInt;
};

int five = addOne(4);

a block named addOne , and an invocation of it.

One slight annoyance – I think all blocks are passed to other functions as id ; there’s no way to say that you expect a block that takes an int and returns another, say.

Available APIs

Asynchronous execution

This is probably the most important part of the platform from my perspective – the app I want to write does a lot of I/O, so making sure this happens away from the UI thread is important.

iOS 4 introduced grand central dispatch (gcd), which seems highly sensible. It rather provokes the question “What the hell did people do before?”, but there you go. The abstractions on top of this don’t seem as rich as android’s AsyncTask framework, but that may be because the presence of blocks makes writing your own abstraction much simpler.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
^{
    NDHResult * result = [fn call];
    dispatch_async(dispatch_get_main_queue(),
    ^{
        [result passTo:receiver];
    });
});

An example of ‘dispatching’ a block to be executed in the background. On completion, a further block is ‘dispatched’ back to the main (UI) thread.

UI framework

The storyboarding provided in XCode makes it, I would guess, much easier for a lay person to get going in creating a layout. Android does have tools for this, but they are considerably more rudimentary, and any serious app will require some fiddling with the underlying XML.

Interestingly, storyboards seem to be relatively new, with many of the older iOS code examples still using a disparate collection of ‘xib’ files to create single views that are then linked together programmatically. As a beginner coming to the platform, this is somewhat confusing; which way is the right way?

I want to write quite a rich app, and I am finding that the storyboard is a bit of a crutch; I’m much happier with android’s HTML like layout model where I don’t really need to learn a complicated GUI tool in order to create a GUI! I suspect I may end up switching to the old style of xibs and doing the work the storyboard is doing in a more obvious fashion.

HTTP

Well, the provided framework is…quite low level; it feels quite like Java‘s HttpURLConnection (HUC), in that all it really wants to do is fling a byte array response at you with a few extra pieces of response metadata. This is, in fact, absolutely fine, as the included json library is perfectly capable of consuming that.

Predominantly, it also wants to behave asynchronously; I’d be interested to know if it’s powered by NIO underneath or a real blocking thread. (I am being evil and doing things synchronously on a background thread anyway, mwahaha.)

One huge upside is the lack of exceptions – each interaction may call you back with an NSError * or the resulting NSData * depending on success (synchronous methods ask for an output parameter in the form of an NSError ** ). This is way better than the clusterfuck of IOException sprinkled all over the Java equivalent.

Side note: one could compare the iOS HTTP library to Apache HttpClient, but that would be somewhat unfair, given the complete mess that android has made of deploying it, and their recommendation to use the HUC API for new apps.

Documentation and process

In general the API documentation is good – one can click through to see the provided header files and a brief google gets you to the equivalent web pages.

Some areas where Android is ahead:

  • StackOverflow answers are much better

  • Available examples tend to be richer, and more up to date …I suspect this is mostly because the “right” way of doing things has moved quite a long way on the Apple side, so it’s less clear what the idiomatic way of doing things is to the community at large.

  • Getting the app on to a real device is trivial for Android, where on iPhone, it’s a nine step marathon that you have to pay them $99 to participate in; this is not at all developer friendly and reminds me precisely why I don’t use iOS devices more generally.

XCode

All I will say is this: within half an hour I was googling to see if IntelliJ supported iOS projects yet. I shall have to give AppCode a try.