Feeds

Making the move to the Mac

Part Two

Maximizing your infrastructure through virtualization

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. ®

Reducing security risks from open source software

More from The Register

next story
HIDDEN packet sniffer spy tech in MILLIONS of iPhones, iPads – expert
Don't panic though – Apple's backdoor is not wide open to all, guru tells us
Do YOU work at Microsoft? Um. Are you SURE about that?
Nokia and marketing types first to get the bullet, says report
Microsoft takes on Chromebook with low-cost Windows laptops
Redmond's chief salesman: We're taking 'hard' decisions
Cheer up, Nokia fans. It can start making mobes again in 18 months
The real winner of the Nokia sale is *drumroll* ... Nokia
EU dons gloves, pokes Google's deals with Android mobe makers
El Reg cops a squint at investigatory letters
Chrome browser has been DRAINING PC batteries for YEARS
Google is only now fixing ancient, energy-sapping bug
prev story

Whitepapers

Seven Steps to Software Security
Seven practical steps you can begin to take today to secure your applications and prevent the damages a successful cyber-attack can cause.
Consolidation: The Foundation for IT Business Transformation
In this whitepaper learn how effective consolidation of IT and business resources can enable multiple, meaningful business benefits.
Designing a Defense for Mobile Applications
Learn about the various considerations for defending mobile applications - from the application architecture itself to the myriad testing technologies.
Build a business case: developing custom apps
Learn how to maximize the value of custom applications by accelerating and simplifying their development.
Consolidation: the foundation for IT and business transformation
In this whitepaper learn how effective consolidation of IT and business resources can enable multiple, meaningful business benefits.