iOS First Impressions

Avatar

James Byatt

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.

Any opinions, news, research, analyses, prices or other information ("information") contained on this Blog, constitutes marketing communication and it has not been prepared in accordance with legal requirements designed to promote the independence of investment research. Further, the information contained within this Blog does not contain (and should not be construed as containing) investment advice or an investment recommendation, or an offer of, or solicitation for, a transaction in any financial instrument. LMAX Exchange has not verified the accuracy or basis-in-fact of any claim or statement made by any third parties as comments for every Blog entry.

LMAX Exchange will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on such information. No representation or warranty is given as to the accuracy or completeness of the above information. While the produced information was obtained from sources deemed to be reliable, LMAX Exchange does not provide any guarantees about the reliability of such sources. Consequently any person acting on it does so entirely at his or her own risk. It is not a place to slander, use unacceptable language or to promote LMAX Exchange or any other FX, Spread Betting and CFD provider and any such postings, excessive or unjust comments and attacks will not be allowed and will be removed from the site immediately.

LMAX Exchange will clearly identify and mark any content it publishes or that is approved by LMAX Exchange.

FX and CFDs are leveraged products that can result in losses exceeding your deposit. They are not suitable for everyone so please ensure you fully understand the risks involved. The information on this website is not directed at residents of the United States of America, Australia (we will only deal with Australian clients who are "wholesale clients" as defined under the Corporations Act 2001), Canada (although we may deal with Canadian residents who meet the "Permitted Client" criteria), Singapore or any other jurisdiction where FX trading and/or CFD trading is restricted or prohibited by local laws or regulations.