Feeds

Making the move to the Mac

Part Two

Boost IT visibility and business value

Last time round, we cautiously dipped a toe into the Mac development waters from the perspective of a Windows programmer with RAD experience. Along the way, I briefly looked at the rudiments of Objective-C syntax, and I described terms such as 'framework' and 'Cocoa'. (Remember, the idea here is not to turn you into a killer Mac coder, but rather to look at the essentials of mainstream Mac development using terminology that's familiar to a .NET, Delphi, C++ or VB developer.)

With this as a basis, let's turn our attention to Xcode and Interface Builder. These are the two main development tools used by a Cocoa developer. (As I said last time, it's perfectly possible to create Cocoa apps using only command-line tools. It's not nice, but if you're that way inclined...)

Xcode

From the viewpoint of a Windows developer, Xcode might seem somewhat lacking. Selecting the File | New Project option gives an impressive looking set of choices. Choose 'Cocoa Application' for a plain vanilla Cocoa app, and you end up looking at a list of boilerplate files which have been automatically added to your fledgling project. But where lurks the form designer? Whither yon component palette?

The answer is that Xcode handles the Objective-C side of things while its partner in crime, Interface Builder, takes care of your GUI window layout. Coming from Delphi, or VB, this seems cumbersome. Truth to tell, it is cumbersome, but I guess you don't miss what you don't know. To fire up Interface Builder (IB for short) look for the file called MainMenu.nib and double-click it.

Historically, the 'nib' suffix stands for 'NeXTSTEP Interface Builder', the great-grandfather of the current IB. In Delphi terms, a nib file is somewhat like a DFM; it encapsulates not only the size and location of every control in a window, but also all the property settings of each control. Finally, it also describes how different objects are linked together via actions and outlets. Actions and outlets? For now, think of this as being similar to event handlers in Delphi or .NET. I'll talk more about actions and outlets when discussing IB, below.

Note: Admittedly, this is something of a generalisation. A nib file doesn't actually have to relate to a GUI element such as a window at all. A nib might contain something like an instance of a non-visual application controller class which is automatically instantiated when your program starts running. Again, this will become clear later.

The Xcode environment has an integrated code editor which I rather like, although it's possible to work with an external editor if you prefer. (Popular alternatives include BBEdit and TextMate.) It also takes care of obvious things like building and running your project, adding new source files, and so forth. Xcode makes it easy to add new frameworks to a project - just drag the wanted framework from /System/Library/Frameworks (or wherever it happens to be) and drop it into the Groups and Files pane of the project window.

Xcode is somewhat let down by the debugger, which will seem relatively crude to anyone who's used to the superb debugging facilities built into Microsoft's .NET development tools. To some extent, Apple are constrained by the need to wrap the IDE's debugging facilities around gdb, the underlying GNU debugger which does all the heavy lifting. If you can't achieve what you want with the visual interface, it's possible to work with gdb directly during a debugging session.

Interface Builder

As mentioned above, IB takes care of GUI layout and is also used to link together different objects. Suppose you want to create a controller class for your application. Within IB, you might subclass the base NSObject class to create a new class called AppController. You would typically instantiate AppController, also within IB. Finally, you would create the source and header files for your new controller class - IB will automatically add them to the current Xcode project.

Back in Xcode, you'll find that AppController.m and AppController.h have been added to your project. But at this point, they don't do much! Try adding the following code to the AppController.m file:

- (void) awakeFromNib
{
  NSLog (@"Hello from AppController...");
}

When you run the app, the expected message will appear in the IDE's Run Log window. So what's happening here? The key point is that when a Cocoa application starts executing, the MainMenu.nib file is automatically loaded into memory and any objects found within the nib are instantiated; you don't have to write the code to do this manually. When all objects in the nib have been un-archived, and after any inter-object connections have been set up, the Cocoa framework sends an awakeFromNib message to each freshly instantiated object, provided that it responds to that message.

The bottom line is that - using IB alone - you can build quite a complex hierarchy of visual and non-visual objects that constitute the backbone of your application&'s structure and visual appearance. You then use Xcode to put flesh on the bones, so to speak.

Earlier, I mentioned actions and outlets. This is the primary mechanism for interconnecting objects. As it stands, our hypothetical AppController object is deaf and dumb - we need to connect it up to the outside world. Back in IB, you might drag a push-button onto the default window. You'll obviously want something to happen when the button is pushed; it makes sense to send a message to our AppController. Firstly, you'll need to define an 'action' for the controller object. Again, this is all done in IB. Once defined, you then (here's the initially counter-intuitive bit!) control-drag the mouse from the push-button to the instance of AppController. This tells IB that we want AppController to do something in response to the button click. IB will present a list of available actions on the controller object. Select one, click the Connect button and you're done.

Back in Xcode, you can then write the code for the action method. It will typically have a signature like this:

- (IBAction) doit: (id) sender
{
  NSLog (@"Oh - that really pressed my button!");
}

As you will appreciate, an action effectively maps from the GUI to program code; whenever the user does something with the user interface, we need to call an action. Contrariwise, an outlet goes the other way, mapping from the code to a GUI element. As an example, consider our push-button control again. Under certain circumstances, we might want to disable the button if it's not appropriate to press it. To do that, the code needs to 'see' the button. An outlet is essentially a pointer to the control. Like actions, outlets are set up when the nib is loaded and processed, before awakeFromNib is called.

Next time, I'll bring the whole thing together by walking you through the development of a small, self-contained application. I also hope to mention Leopard (Apple's soon to be released operating system) with special emphasis on the changes and improvements to both the development tools and to Objective-C itself. That's assuming it's been released by this time next month. If not, my lips will have to remain sealed!

In the meantime, here's the URL of a small pdf file which gives a good introduction to the Objective-C language. Definitely worth a read. ®

Build a business case: developing custom apps

More from The Register

next story
KDE releases ice-cream coloured Plasma 5 just in time for summer
Melty but refreshing - popular rival to Mint's Cinnamon's still a work in progress
Leaked Windows Phone 8.1 Update specs tease details of Nokia's next mobes
New screen sizes, dual SIMs, voice over LTE, and more
Mozilla keeps its Beard, hopes anti-gay marriage troubles are now over
Plenty on new CEO's todo list – starting with Firefox's slipping grasp
Apple: We'll unleash OS X Yosemite beta on the MASSES on 24 July
Starting today, regular fanbois will be guinea pigs, it tells Reg
Another day, another Firefox: Version 31 is upon us ALREADY
Web devs, Mozilla really wants you to like this one
Secure microkernel that uses maths to be 'bug free' goes open source
Hacker-repelling, drone-protecting code will soon be yours to tweak as you see fit
Cloudy CoreOS Linux distro declares itself production-ready
Lightweight, container-happy Linux gets first Stable release
prev story

Whitepapers

Implementing global e-invoicing with guaranteed legal certainty
Explaining the role local tax compliance plays in successful supply chain management and e-business and how leading global brands are addressing this.
Boost IT visibility and business value
How building a great service catalog relieves pressure points and demonstrates the value of IT service management.
Why and how to choose the right cloud vendor
The benefits of cloud-based storage in your processes. Eliminate onsite, disk-based backup and archiving in favor of cloud-based data protection.
The Essential Guide to IT Transformation
ServiceNow discusses three IT transformations that can help CIO's automate IT services to transform IT and the enterprise.
Maximize storage efficiency across the enterprise
The HP StoreOnce backup solution offers highly flexible, centrally managed, and highly efficient data protection for any enterprise.