8 Feb 2010

On Objective-C and iPhone development

Posted by admin

The last number of years I have mainly developed software in Java for obvious reasons. Before that I’ve done C, C++, Algol 68, Pascal and some Cobol too. Recently I acquainted myself with writing software for Apple’s iPhone which of course takes place in the Objective-C language.

Language food fight
Like Java and C++, Objective-C builds on top of C in terms of its syntax. Unlike Java, Objective-C is a strict subset (or superset, depending how you look at it) of C: anything one can do in C, one can do in Objective-C. This is immediately the key material for deep, lengthy, philosophical debates – best done in a pub – whether this is Good or Bad. I think it is neither: the designers of both languages come at it from different viewpoints. Java imposes some rigidity on the programmer to protect against common mistakes in order to increase the programmer’s productivity. Objective-C gives the programmer all the freedoms of C plus object oriented programming concepts in order to increase the programmer’s productivity.

While both languages claim similar ancestry for their syntax, the outcomes are quite different thus as a Java programmer it takes a bit of time to comfortably read Objective-C code. Besides the syntax, one of the main differences between the two is how they treat null pointers. Let me give quick examples of both the syntax differences and the null pointer treatment.

I have a MapPin class which has this initialization method defined in the header file:

- (id)initWithCoordinates:(CLLocationCoordinate2D)location
                                placeName:(NSString *)placeName
                                description:(NSString *)description;

And here’s how it gets called:

MapPin *pin = [[MapPin alloc] initWithCoordinates:location
                                                         placeName:@”Start”
                                                         description:@”"];


In Java this would look like:

public void initWithCoordinates(CLLocationCoordinate2D location,
                                                String placeName,
                                                String description) {
        ….
}

And invoked like:

MapPin pin = new MapPin();
pin.initWithCoordinates(location, placeName, description);

Regarding null pointers take this Objective-C snippet – it loads an image from a web address and then writes the data to a local file:

NSURL *imageURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@“%@%@“, kWebLocation, imageName]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
profile.image = [UIImage imageWithData:imageData];
[imageData writeToFile:myLocation atomically:YES];

If the requested image does not exist at the web address or if there’s no internet connection then imageData will be nil. In Java we need to check for that before calling the writeToFile method on imageData to avoid a possible null pointer exception. In Objective-C when imageData is nil the writeToFile message is not sent. Coming from Java this takes a while to get to grips with but when used well allows you to write very compact code where the existence or non-existence of objects determine the behavior of the code.

There are of course many more differences between the languages. If like me you are coming to Objective-C from Java then I highly recommend Bucanek’s book (see Resources below).

All IDEs created equally?
In many cases you experience a programming language and platform not by themselves but through an IDE. The code excerpts above already show a little of that: the syntax coloring come from XCode and Netbeans respectively. Developing for iPhone means developing with XCode. XCode plus Interface Builder in many cases. I like Netbeans. In the beginning of Java I favored Borland’s JBuilder but for years now I happily interact with Netbeans. I found XCode quite easy to get along with. It has a broad set of templates when creating new classes. Its code completion is pretty good and fast. You can debug your app in the simulator but also directly on the device.

My main learning curve was the integration between XCode and Interface Builder (IB). For laying out the user interface IB is very good: much nicer and smoother than Netbeans’ matisse layout for example. But I expected IB to do more code generation: the need for IBOutlets and IBActions in XCode and how to connect them in IB took a while to grasp. Then there’re some usability nuisances like forgetting to save in IB before building and testing in XCode. Tighter integration between the two would be nice.

I like Netbeans’ debugger better than XCode’s. My main two issues are that the XCode compiler often optimizes away local variables making it hard to check whether your code exactly does what you intended, and I haven’t found a way to get it to display long strings (the debugger view truncates them).

The map is not the land
A typical workflow will be: write some code, do some layout in IB, build, test in iPhone Simulator and repeat. It’s quick and neat. The iPhone Simulator can mimic incoming phone calls, low memory situations, rotation of the device, shaking the device and so on. If the application works well in the simulator then it’ll work well on the device. However, testing on the device is still necessary: the simulator is not your iPhone. An obvious one is that the real world presentation of your app on the device will be slightly different than in the simulator: what looks good on the simulator may not look as good on the device.

But perhaps more importantly there are a few key behavioral differences. Like Java, iPhone has a concept of a sandbox. An application is allowed access to a few specific locations on the device and not anywhere else. Oddly, Apple hasn’t fully replicated this in the simulator and so this snippet of code works perfectly in one but fails in the other:

NSString *myPath = [[NSBundle mainBundle] pathForResource:kRidesFile ofType:kFileType];
NSArray *ridesArray = [[NSArray alloc] initWithContentsOfFile:myPath];
….
[ridesArray writeToFile:path atomically:YES];

It reads in a file from the application bundle containing bicycle routes and then writes it out again. Well, so, it writes it out in the simulator but not when running on the device. The sandbox prohibits writing to the application bundle only allowing write operations to other specific locations (tmp, cache or documents).

Javadoc where art thou?
When working on my iPhone project I regularly have deja-vu feelings to the first half of the nineties when I developed Macintosh applications using C++ and MacApp: you know there’s a class and method that can do what you need but how to find it?

I’ve always believed that Javadoc was/is one of Java’s strong points. The iPhone OS Reference Library is not bad but it still leaves too much hunting to the developer, for example in finding inherited methods and properties causing a lot of browsing back and forth (which is contributed to by the browser’s back button going to the previous page rather than the top of the page…).

Some observations
Syntax-wise and from a design perspective I still favor Java. With C, C++ and now Objective-C I’ve always had the feeling I need to type the same stuff twice; in the header file and the implementation file. And I don’t enjoy the hunting for dangling pointers – I am all for garbage collectors.

I recommend to do a ”Build and Analyze“ in XCode frequently and let the IDE help you find memory management issues that deserve your attention.

But Objective-C and the iPhone class library do have some very nice aspects too, in particular the property mechanism, the nil pointer and working with files. The initWithContentsOfFile method above is all that’s needed to get structured information from a file: an array one can then iterate over. And writeToFile to save it.

Resources

Subscribe to Comments

2 Responses to “On Objective-C and iPhone development”

  1. [...] Follow this link: Onno-Consulting.Com » Blog Archive » On Objective-C and iPhone … [...]

     
  2. >and I haven’t found a way to get it to display long strings (the debugger view truncates them).

    Do the following:

    XCode Preferences: Choose for layout “All in One”. Much better! While debugging is is possible to examine the variables in the upper pane. Press Ctrl-Click on a variable and select “View in Window”. This will display the variable in a window as wide as you like.

     

    Leon Wubbe

  • Browse

    or
  • Let’s Connect

    Email:
    onno@onno-consulting.com
    AIM:
    onnoweb
    Phone:
    +1 585 733 5130
  • Twitter

  • Software

    Club Rides - keeping track of your cycling club's activities

    GPX2ProfileImage - elevation profiles from GPX files

  • Social Homes

    LinkedIn  Twitter  Naymz  
  • Recent Posts

  • Tag Cloud

  • Calendar

    February 2010
    M T W T F S S
    « Jan   Mar »
    1234567
    891011121314
    15161718192021
    22232425262728
  • Meta