May 28, 2009

SQLite optimization on the iPhone

Our current iPhone application makes quite heavy use of SQLite. We persist the model in the database using a Data Access Object pattern built on top of my own JDBC like SQLite layer and it is all still quite lightweight. CoreData whould have been prefereable but we have to be compatible with iPhone SDK versions prior to 3.0. We also use the database to rank trends using indexed and weighted keywords and some additional temporal factors. Thankfully the text data we search through on the device is pre-indexed so we don't have to worry too much about getting suitable data into the tables. However we do need the database to run queries against this data and we spotted early on that optimization would be beneficial here.

I had some ideas of where we could improve and with a little Googling I found a sparse but useful SQLite optimization FAQ compiled by Jim Lyon. I quickly put together a hit list of optimizations that I'd try.

Use a between construct instead of LIKE
The FAQ explains that a LIKE cannot use an index and thus where possible it should be replaced with the > and < operators. For example:

    word LIKE 'dog%'

Can be replaced with the more efficient:

    word > 'dog' AND word < 'doh'

It's not a trivial replacement. Firstly the strings you are comparing must be of one case only. I also ran into trouble with international characters which of course don't fit nicely into the byte ranges. Furthermore you must write a little logic to generate the last character(s) of the 'upper limit term' (in this case 'dog'). Incrementing the last character is all well and good - but what about when you want to perform:

    LIKE 'oz%'

I simply appended a low value character to the string to obtain the 'upper limit term' and ended up with something like: 'oz!' Thankfully I could work within these limitations for our use-cases and performance was much improved.

Move members of IN clauses into temporary tables
Many of our queries used variable length IN clauses. This made it unfeasible to prepare and cache the resultant statements and they would be prepared fresh each time. This sucked up and incredible amount of time - we might spend a second just preparing the statement. A typical clause is shown here:

    AND id IN (32, 45, 67, 68, 80)

I decided that if I moved these values into a temporary table I could use a sub-select within the IN clause and hence end up with a static statement that I could prepare once and cache:

    AND id IN (SELECT id FROM temporary_ids)

In addition to this I hoped to use a PRAGMA directive described in the FAQ to move the temporary tables off of the flash disk and into memory:

    PRAGMA temp_store MEMORY

However, this setting does not seem to take effect on the iPhone version of SQLite which was somewhat disappointing. That said, the restructuring of my IN clauses did provided yet another significant performance improvement. I wouldn't be surprised if the row inserts into the temp table actually take longer than the execution of a given IN clause. But in this instance I am avoiding the costly preparation of a statement on each call.

Order sub-queries so that smaller results are returned first
The FAQ suggests in section 5.3 that sub-queries or criteria should appear in an order such that the criteria that will exclude the most rows should appear first. I take this to mean that this (poor) example query:

    SELECT o.id
    FROM owner o, pet p
    WHERE o.age > 12 AND p.name = 'nathan' AND p.id = o.pet_id

Should be rewritten as:

    SELECT o.id
    FROM owner o, pet p
    WHERE p.name = 'nathan' AND o.age > 12 AND p.id = o.pet_id

Because the p.name criteria is far more selective than that using o.age. Okay, so it's not a great example query. However, in our queries it was quite clear which criteria would be the most selective.

Other practices
Prior to implementing these optimizations we were using many of the best practices recommended in the FAQ including:
  • Batching commands into transactions
  • Using indexes where appropriate and justifying the indexes with the EXPLAIN command
  • VACUUMing the database file before making release builds - this had a noticeable effect on the database file size but I couldn't say that it improved the performance.

Never forget

Often when we are developing applications for the iPhone we want to enable extra 'tools' in the execution environment so we can get a better grasp of what our software is actually doing. Typically we'll use some kind of logging, and after reading Adhamh Findlay's post on the use of NSZombie I'll often have NSZombieEnabled turned on.

Both of these tools will have an impact on the behaviour of our application if enabled. Logging will certainly slow the application down and NSZombie can make the app run out of memory. Therefore, we need to be conscious of these potential hazards so that we don't try to start fixing problems that are actually just artifacts of the tools. More importantly we must be certain that none of these useful developer settings make their way into released code. It's not hard to imagine that one could let logging slip into a build - at a minimum this will cost you another cycle of building a release and potentially much, much much more.

We found ourselves making this mistake a couple of times with internal releases so thankfully it was only QA who complained and not customers. But having made this mistake we resolved to make it very difficult to repeat. So here's the first thing that our developers see when they start-up the application in a development mode:


Sure, dismissing the alert is a little annoying but it reminds us of the particulars of the current execution environment and saves us from making a costly mistake. We can then release our software with greater confidence. From a code perspective it's lightweight - in our viewDidLoad method of our root UIViewController we call:

    [ForgetfulDevelopersAlert showDeveloperWarningIfRequired];

In the ForgetfulDevelopersAlert implementation we check for logging like so:

    BOOL logging = NO;
    #if LOG_LEVEL != NONE
        logging = YES;
    #endif

And we detect for NSZombie usage with:

    + (BOOL) __isNSZombieEnabled {
        return getenv("NSZombieEnabled")
            || getenv("NSAutoreleaseFreedObjectCheckEnabled");
    }

With these flags available it is straight forward to construct a message and show the UIAlert:

    if (logging || zombies) {
        UIAlertView* alert = [[ForgetfulDevelopersAlert alloc]
            __initAlertWithLogging:logging andZombies:zombies];
        [alert show];
        [alert release];
    }

This can of course be extend to check for other development settings. For example I know of one particular case where an app was submitted to the AppStore and it was not noticed until it had finally been approved that only 'test' ad banners had been enabled. Potentially this lost some revenue and required another approval cycle with Apple - but it is a very easy mistake to make that perhaps could have been avoided with something like:

    [ForgetfulDevelopersAlert showWarningIfTestAdsEnabled];

:-)

May 27, 2009

Private properties for iPhone Objective-C

Keeping members private is extremely important in Object Oriented design as it allows us to adhere to the principles of encapsulation and information hiding, and makes it easier to keep our objects thread safe. We often want to use @properties in Objective-C to take care of retain counts in setters for us. However, unless you are careful these properties will always be public. This 'kitchen sink' approach results in all of your internal object state being exposed on your public API. This is dangerous because:
  • Developers can modify the internal state of your objects when they shouldn't
  • Developers are 'tempted' to access things that they shouldn't as they can see 'apparently useful' things on the interface.
  • Developers are confused when they read the interface - they need to somehow work out which public properties they can use and which they can't.
In short: NEVER expose class internals publicly - it is very bad OO practice.

Private setters are discussed in Scott Stevenson's Objective-C tutorial, but the post does not explain how to make both the setter and getter private - furthermore I was tripped up by a coupled of points that are not illustrated in Scott's examples. So how do we create completely private properties in Objective-C? The steps are as follows:
  1. Make the member variable @private. This is not essential to create the property but if we're making the property private then it'd be wise to make the member variable accessible only from within our class.
  2. DO NOT declare the property in the main @interface in the header (.h) file
  3. Create an @interface for an extension (unnamed category) in the .m file ABOVE the @implementation
  4. Declare your private @property in the extension interface
  5. @synthesize the private property in your @implementation as normal.
See code below for an example:

ClassWithPrivateProperty.h

    @interface ClassWithPrivateProperty : NSObject {
    @private
        NSString* member;
    }
    - (void) trySettingPrivateProperty;
    @end

ClassWithPrivateProperty.m

    #import "ClassWithPrivateProperty.h"
 
    @interface ClassWithPrivateProperty ()
    @property (nonatomic,retain) NSString* member; 
    @end
 
    @implementation ClassWithPrivateProperty
    @synthesize member;
    - (void) trySettingPrivateProperty {
        self.member = @"A Value";
        NSLog(@"myClass.member = %@", self.member);
    }
    @end

May 25, 2009

A simple concurrency framework for the iPhone

The iPhone app we're working on has become quite large and complex - necessarily so. However, from the start of development many months ago the product has grown organically. Although almost feature complete - the app was quite unstable and failed to deliver in terms of performance so some refactoring was needed.

As I worked my way through spaghetti code, I came across many threading objects and asynchronous calls that were initiated and 'managed' all over the application, sometimes in the view, sometimes the model, and sometimes on the controllers. This effectively made it impossible to determine what the application was doing at any given time. To make matters worse it it was not clear that we were being thread-safe as access to some shared data was unsynchronized. These findings were the likely root of our stability issues. In addition to this we found some tight thread-sleep loops. These were a possible candidate for some performance issues but also a total abomination.

To tackle these issues I had a plan. I would create a framework that provided the threading functionality required by our application use-cases in a safe and centralized manner. I'll now describe the framework.

The foundation of the framework is an old favourite - the command pattern. Any piece of work we want to do on a thread - be it make an HTTP call, parse a document, or asynchronously write to the database - is expressed as a command. In practice we must implement a protocol:

    @protocol Command
    - (void) execute;
    @end

Concrete command classes usually pass some input parameters in the constructor and provide an accessor so that the caller can extract any result of the processing that takes place in the execute method. The execute method implementation is the 'stuff' you actually want to DO be it synchronously or asyncrhonously.

Fundamentally the framework executes commands. However, regardless of your concrete command implementation - the framework can execute your command in a synchronous (blocking) or asynchronous manner. What a relief for the developers - forget about how we safely do something asynchronously and concentrate on the thing you actually want to DO. The framework provides the following methods on the core class - CommandSchedulerQueue - for command execution:

    - (void) addCommandToQueueAndReturn:(id<Command>)command;
    - (void) addCommandToQueueAndReturn:(id<Command>)command 
        withCallback:(id<MutableCallback>)callback;
    - (void) addCommandToQueueAndWait:(id<Command>)command 
        withTimeoutInSeconds:(NSInteger)timeout;

As the method names suggest - the framework provides a command queue internally which mandates that the commands be executed in the sequence that they were added to the queue. This may sound a little restrictive but it is perfectly possible to create multiple command queues or even allow more than one command to be executed concurrently on a given queue by allocating the queue more threads.

So before I describe the functionality given to commands and callbacks by the framework, let me mention what's going on inside the framework - and specifically the thing we call the CommandSchedulerQueue class. From the outset I wanted to stick to using well understood Foundation components and classes. Indeed the Foundation framework provides a rich set of classes to deal with concurrency - so use them! At the core of the CommandSchedulerQueue class is an NSOperationQueue, we wrap our command execution in an NSOperation and schedule it on the operation queue. This is nothing new - our application used NSOpeationQueues in the past but often created them all over the place and applied them in an inconsistent manner. By wrapping an NSOperationQueue in our CommandSchedulerQueue we can add useful behavior and hide NSOperationQueue specifics that previously tempted developers to do undesirable things.

So what kind of behavior do we add to the command execution?
  • We can block the caller until the operation - or rather the command - is complete. We do this in a safe and performant manner using the NSCondition class.
  • We can invoke a callback to the caller if they have scheduled a command to be executed asyncronously.
  • We can capture an exception raised during the command's execution and either  throw it back to the caller immediately if the command was executed synchronously, or we can deliver the exception in the callback in the case of asynchronous execution.
Let's take a look at the callback:

    @protocol Callback
    - (void) callbackInvokedForCommand:(id<Command>)command;
    - (void) throwExecutionException;
    @end

    @protocol MutableCallback <Callback>
    - (void) setExecutionException:(NSException*)exception;
    @end

When implementing the callback for a command we need to provide the behavior of the callbackInvoked method - i.e what we want to happen when the callback is finally fired. Often we'll want to send a message to the original caller to tell them that their command is no longer executing. The receiver of the callback can then invoke throwExecutionException to handle any exception that occurred during the execution of the command. An implementation of throwExecutionException is actually provided in an abstract <MutableCallback> implementation and the CommandSchedulerQueue knows how to set the exception within the callback object.

So that's the basic framework. In our iPhone application we now put all concurrent functionality through this framework which allows us to keep the threading complexity in one place and provides us with excellent visibility on what the app is doing at any given time. We can schedule commands knowing that they'll be executed in sequence and with the confidence that we won't miss any exceptions thrown - even if they're thrown on another thread. Finally we can schedule operations and block until completion in a clean manner (no tight thread-sleep loops!) while hiding the specifics of NSCondition.

May 3, 2009

Code as prose

I recently started reading Clean Code - and immediately felt guilty for not reading it earlier. In the first few pages Grady Booch suggests that clean code should read like prose. If we take this a little further use an analogy where the code of an application could be thought of as a book we could then ask the question: 'How would the the shelves of our local bookshop appear?' Their contents would surely reflect the current state and quality of IT projects at large.

Personally I think there would be a fair few fine works of prose and many of those you could take home for free. However, the majority of those shelves would be chock full of vaguely similar children's colouring-in books that have been carelessly scribbled in. Markings from the 'crayon of implementation' would wildly stray over the clear and purposeful black outlines of original intent.

Flickr is surprisingly devoid of badly executed 'colouring-ins' but has no shortage of perfectly filled pages from such books - perhaps this is yet another example of sunlight being the best disinfectant

Revisiting JDBC (pt. 1)

About 6 or 7 years ago I was writing a lot of SQL and JDBC - I remember being particularly pleased when I developed an efficient implementation of Celko's Nested sets to represent hierarchical data in a Content Management project. At the time JDBC was a pretty neat way of interfacing with a relational database. However, we Enterprise Java developers have for the most part left JDBC behind in favor of excellent ORM frameworks such as Hibernate and although we are using JDBC more that ever, we do so with it operating under the covers - tucked away within our ORM framework. Sure there may be times when we have to step back to JDBC - how well would Hibernate handle hierarchical data? - but they are infrequent.

Now as I mentioned in previous posts, the main reason I found myself developing - well, debugging at first - on the iPhone platform was to investigate why a SQLite based feature of our application wasn't functioning as well as the original Java proof-of-concept. Fairly soon I was immersed in the world of SQLite's C/C++ interface - JDBC this was not. From a Java point of view it's low-level: Error conditions signaled by return value on almost every function and pointers aplenty. What I wanted was JDBC - or rather OBJCDBC - but in fact I wanted much more because in the JDBC world I had also become used to:
  • Excellent connection and prepared statement pooling with the likes of DBCP.
  • Concise utility methods that allowed me to avoid JDBC boiler-plate in the form of DbUtil.
I Googled a while to see if such a thing existed in the iPhone domain and thankfully found many likely candidates on the SQL Wiki (see: Objective-C section) ranging from simple wrappers to ORM frameworks. However, the simple wrappers were not as clean and object orientated as I was used to with JDBC and the ORM frameworks would not give me enough control to write some of the highly optimized SQL queries that our application demanded. I set about writing my own wrapper. One could argue that I was reinventing the wheel - but I'm always happy to learn more about wheels. My requirements were as follows:
  • Option to pool connections and statements
  • Check for every error condition that SQLite could possibly set and convert these into exceptions so we can adopt a try/catch/finally approach when accessing the database.
  • Provide a clean and simple programmatic interface.
  • Move all direct interactions with SQLite into a few sensible classes - C based SQLite code had previously been spread liberally throughout the application.
My core classes were to be as follows:
  • PooledDataSource - A connection data source that also pools connections. Calling close on a connection actually returns it to the pool.
  • Connection - Encapsulates a SQLite database handle - can also pool statements that have been prepared from this connection. Calling prepare on a connection might actually fetch and reuse a pooled PreparedStatement rather than creating a new instance. rovides methods to manage transactions.
  • PreparedStatement - Prepares transient and non-transient statements, binds parameter values to statements, and executes statements. Returns ResultSets for SELECT queries. Calling close on a prepared statement returns it to the statement pool if it is not transient.
  • ResultSet - An interface for stepping through a cursor and retrieving values from the row.
With these classes in place I could write some typical Data Access Object code:

    PreparedStatement statement;
    ResultSet results;
    NSNumber maxId = nil;
    @try {
        stmt = [con prepare:@"SELECT MAX(id) FROM foo WHERE bar = ?"];
        [con begin]; // OK - so we don't need this for a SELECT
        results = [stmt executeWithValues:@"dog", nil];
        if ([results next]) {
           maxId = [results getInt:1];
        }
        [con commit]; // for illustration only
    @catch (NSException* sqlX) {
        [con rollback]; // for illustration only
        // handle error
    } @finally {
        [DatabaseCommons closeQuietly:results, statement, con];
    }

I'll get more into the actual class implementation details in part 2.


May 2, 2009

Dynamic Proxies

Part of our iPhone application uses proxy objects lazily load the full-fat objects behind the scenes. The initial implementation simply used an object that had the same core interface of the proxied object and used a factory to load the full-fat object in the event that a property was called on the proxy that it couldn’t service with it’s own internal state.

    @implementation MyProxyClass // : NSObject ...
    -(NSString*)doSomethingIntensive {
      if ([self fullFatObjectNotLoaded]) {
            [self loadFullFatObject];
        }
        return [fullFat doSomethingIntensive];
    }
    ...

This was all well and good - but eventually the model sitting behind the proxy grew and grew until we had a rather large hierarchy of classes that had to be managed by the proxy. To do this the proxy would have to present all of the varied properties on all of the classes in the model hierarchy. In development terms alone this wasn’t scalable - we’d keep having to add new properties to the proxy as they were added to the model; instead a shortcut around this issue had been implemented. The proxy exposed the full-fat object with it’s own getter:

    @interface MyProxyClass : NSObject ...
    -(MyClass*)getFullFat;
    ...

The problem with this is of course that now the caller to the proxy must actually know about the proxy - it can no longer just use the MyProtocol protocol (Java: ‘Interface’) and must now be aware of the type ‘MyProxyClass’. This makes the calling code tightly coupled to the lazy loading process - exactly what we don’t want.

As enterprise Java developers we see dynamic proxies intercepting calls to our classes everywhere in our EJB containers, Dependency injection frameworks (e.g: Spring, Seam), and ORM frameworks (Hibernate for example). In truth we rarely see them - perhaps in a call stack in the debugger - but we know they are there wrapping rich services around our objects without our intervention.

What I wanted was something similar for our iPhone application - some kind of Objective-C dynamic proxy that could seamlessly proxy our (perhaps overly) complex model and remain hidden from the classes who would actually be be calling the proxy.

Now writing a dynamic proxy service in Java is probably difficult. I haven’t written one but I imagine it entails reflection and byte code generation - not necessarily the stuff that the average Java developer gets stuck into. Besides - there are good libraries that do this already and do it well in the Java world. However - in the world of Objective-C it is surprisingly easy to do out of the box using a Foundation class named ‘NSProxy’.

Any selector messages (Java: ‘method calls’) invoked on the proxy invoke a default method on the proxy called ‘forwardInvocation’ including a description of the invocation (selector, arguments, etc.) By overriding the ‘forwardInvocation’ method we can route the method invocation wherever we like. In the case of our lazy loading proxy we’d like to check to see if our proxy can service the invocation (we can use 'respondsToSelector' for this) and if not - load up the object we are the proxy for and then forward the invocation to that full fat object like so:

    @implementation MyProxyClass // : NSProxy ...
  -(void)forwardInvocation:(NSInvocation*)invocation {
      SEL selector = [invocation selector];
     if ([self fullFatNotLoadedAndCanBeHandledByProxy:selector]) {
        [invocation setTarget:lowFat];
    } else if (fullFat != nil) {
       [invocation setTarget: fullFat];
    } else {
       NSAssert(FALSE, @"Hope this never happens");
     }
     [invocation invoke];
     return;
  }

Of course - it’s a bit more complicated than that. NSProxy is not an actual object as such - it’s not a subclass of NSObject. So if you send an ‘init’ invocation to a NSProxy instance it doesn’t actually call the init (Java: ‘default constructor’) on the proxy instance - it doesn’t have one. Instead this is treated like an other method and we find that we have an invocation of ‘forwardInvocation’ with selector ‘init’. And in this event what object reference should we return to the caller? It gets even more confusing when we find that calls to extremely type specific methods such as: ‘isKindOfClass’, ‘conformsToProtocol’, and ‘respondsToSelector’ also get directed straight to ‘forwardInvocation’ and that we have to handle those too! How confusing - this would never happen in Java!

So this is the way that I chose to implement the lazy loading proxy:
  • The proxy would have an internal ‘low-fat’ skeleton object that acts as a placeholder for the proxied object - in my case it had a member that held the full fat objects database ID. The low fat object is alloced when the proxy gets a request for the NSMethodSignature for the initWithId method - the proxy passes a reference to itself - not the databaseId - we have to wait for the 'forwardInvocation' call to get at the method call argument.
    @implementation MyProxyClass // : NSProxy ...
    ...
    -(NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
        if (selector == @selector(initWithId:)) {
            if (lowFat == nil) {
                lowFat = [[LowFatObject alloc] initWithProxy:self];
            } else {
                NSAssert(FALSE, @"Hope this never happens");
            }
        }
        ...
    }
    ...
    @end

    @implementation LowFatObject
    @synthesize databaseId;
    -(id)initWithProxy:(MyProxyClass*)aProxy {
        if (self = [super init]) {
            proxy = aProxy;
            // NOTE: 'proxy' member of type MyProxyClass!
        }
        return self;
    }
  • The ‘initWithId’ call to the proxy would actually be routed to the low-fat object to but note that the low fat object has already been alloced and init'ed by the proxy. So instead it adopts the databaseId value and (importantly) returns a reference to the proxy - not itself.
    @implementation LowFatObject
    -(id)initWithProxy:(MyProxyClass*)aProxy...
    ...
    -(id)initWithId:(int)aDatabaseId {
        databaseId = aDatabaseId;
        return proxy;
        // We want the caller to have a ref to the proxy!
    }
  • We're still left with the issue of deciding when to load the full-fat item. To do this we need to check if the low-fat skeleton object is able to service the invocation and if not we need to load the full-fat object and set that as the invocation target. We do this when we're asked to supply the 'NSMethodSignature' for the pending invocation. Before we dive into this recall that the invocation could be for something where the return type is extremely type specific - such as 'respondsToSelector' - in those eventualities we MUST also load the full-fat object because only the can we really know what the object we are a proxy for is actually capable of.
    @implementation MyProxyClass // : NSProxy ...
    ...
    -(NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
        ... init method handler ...
        NSObject* target;
        // Is the selector extremely type specific?
        if (selector == @selector(isKindOfClass:)
            || selector == @selector(conformsToProtocol:)
            || selector == @selector(respondsToSelector:))
        {
            [self loadFullFatTarget];
            target = fullFat;
        } else if ([self fullFatNotLoadedAndCanBeHandledByProxy:selector]) {
            // The low-fat item responds to the selector
            // and the full-fat hasn't been loaded
            target = lowFat;
        } else {
            // We need to load the full fat because the low-fat
            // skeleton can't handle it
            [self loadFullFatTarget];
            NSAssert1(
                [fullFat respondsToSelector:selector],
                @"Neither full/low fat object can handle selector %@",
                selector
            );
            target = fullFat;
        }
        return [target methodSignatureForSelector:selector];
    }

Despite being a little fiddly this approach has worked quite well in practice. As a Java developer it's quite refreshing to be able to construct something as powerful as a Dynamic Proxy using a core class supplied in the SDK. Although the model we are proxying probably has much room for refactoring we can now at least add and remove properties from the model classes and have them implicitly supported by the proxy without any further modification to the proxy itself.

From (My)Eclipse to XCode

As any Java developer worth his salt knows - if you’re going to be writing code in a productive way - you should at least know a handful of keyboard shortcuts in Eclipse. Yes I’m sure others use Netbeans and IntelliJ IDEA - but I have met them rarely and they often seem to have selected their IDE just to be different, awkward, or both (flame war starts here).

So important is the knowledge of shortcuts that I’ve often seen them on cheat sheets, stuck on the side of mugs, and described incredulously in code reviews when one developer who knows a shortcut, watches the other developer painfully scroll through a menu or type out a class name. Some developers - so happy that they’ve discovered something powerful - email all of their developer friends with the newly learnt shortcut only to be ridiculed in a barrage of replies with sentiments to the effect of: ‘You’ve been earning £X00 a day developing with Eclipse for 5 years and you didn’t know about shortcut X?’

So anyway, my first big hurdle with XCode was shortcuts. Without those I could not be as productive as I’d like. In fact - that wasn’t my first hurdle - first I needed to stop using Eclipse shortcuts in XCode.

So I’ll list my favorite XCode shortcuts. They are there in the preference panels, in books and on the side of mugs. But if like me you can’t be bothered to look and would rather have someone else tell you here they are:
  • alt-cmd-up: Switch between header and implementation file
  • alt-cmd-left: go to previous file
  • alt-cmd-right: go to next file
  • cmd-b:  start/stop build
  • shift-cmd-k: clean all targets
  • cmd-return: build and go (launches the iPhone simulator/device with your app)
  • shift-cmd-d: find a source file
  • shift-cmd-f: find text in the project sources

Background

So a little bit of background. I have been happily developing with Java for over 9 years and am very appreciative of the wealth of frameworks available that make my job easier and more productive. In the company I work for currently I have been developing an enterprise server side Java application whose job is to aggregate and feed data to an iPhone based client. It got to the point where the server was virtually complete, scaling well and had few additional features remaining in the product backlog. We ‘server guys’ had applied best practices, patterns, and frameworks with a very satisfactory result.

I then began architecting features of the iPhone client application - with no intention of actually developing on the platform but merely providing the iPhone developers with a proof of concept that they could effectively ‘transcribe‘ into the iPhone domain. The feature in question required an SQLite database on the iPhone and as a server guy I could throw SQL together with ease - so it made sense that I should do the design. However, as the iPhone implementation of my designs progressed, many issues presented themselves on the client that just didn’t exist in my Java-based proof of concept. It was at this point I realized that I’d have to delve into the world of Objective-C and XCode. Having done a bit of C programming at university and written one MFC based OpenGL app for my coursework 12 years previous - I was struck with fear at the learning curve I probably faced.

I was very pleasantly surprised. In terms of language structure and syntax - the core things that make Java development easier (or rather: less difficult) than C were all in place in Objective-C. Exceptions, Thread classes, synchronization, interfaces, etc. were there - although often they are often called something totally different and aren’t quite like the Java equivalent. I was given Dylan McNamee’s ‘Java to Objective-C cheat sheet’ which proved a useful starting point and I was soon at ease. Then, having had a quick look at the language I wanted to get started debugging the iPhone implementation of the SQLite POC.

I’d recommend that any Java developer interested in the iPhone platform jump right in - they won’t find the learning curve that steep and in my opinion you can apply all the software development fundamentals that one is often required to know in the Enterprise Java domain to this (much smaller) platform.

Why this is here

As an experienced Enterprise Java developer forced onto the iPhone development platform, I have noticed many opportunities where the experience I have gained in the enterprise can be used to good effect on even Apple’s smallest public platform.

To me at least it seems that Java developers with some good development experience behind them can lend much to this relatively new platform and the community that is rapidly building up around it. I did not find this so much to be the case when working with J2ME which at the time (2004) made it prohibitively expensive in performance terms to stick rigorously to respected patterns and frameworks. The iPhone platform is arguably far more powerful than that J2ME stack I developed for in the past and therefore allows the developer to pay more attention to good design and development practice.

In this blog I hope to look at problems encountered on the iPhone platform and how they were solved with lessons learned from J2EE development.