Cheat Sheet

Mac Application Development For Dummies

Macintosh application development requires creativity, Objective-C programming skills, some patience, and a nice helping of persistence to implement, refine, and deliver your Macintosh application in good working order to your users. On your way to this destination, you’ll encounter some challenges that will test your programming and problem-solving skills. You must come to grips with (among other things) using delegates to implement application callbacks; using non-Objective-C frameworks from Apple; and incorporating C++ code into your apps.

Implementing Callbacks in Macintosh Applications

Macintosh application development uses callbacks to allow Mac OS X to execute code within your app for specific operations. If you’re creating a standard Macintosh window- or document-based app, the very first code that OS X will execute is in one of the following callback methods you have to create for your app, depending on the app design:

  • Window-based apps: (void)applicationDidFinishLaunching:(NSNotification*)aNotification

  • Document-based apps: (void)windowControllerDidLoadNib:(NSWindowController*)windowController

A callback is simply a method that the OS eventually executes while it’s trying to supply or retrieve information from your app. Your application code will execute a method for a Cocoa class where your app will have the opportunity to provide the name of a method of one of your classes, to be called on an object of that class your app will also have to provide.

A delegate is a helper object, which a Cocoa class uses to extend the functionality of the class by allowing you to implement code which the Cocoa class will execute in certain circumstances. A Cocoa class checks its delegate object (if one has been assigned) for whether the delegate provides an implementation of a specific method. If the delegate has that method, the Cocoa class executes that method; if the delegate doesn't implement that specific method, the Cocoa class either uses a default method of its own or logs an error. Most delegates must incorporate a particular protocol that determines what methods they may implement; your code’s delegates must use the implement methods from the specific protocol that the delegate expects.

Here are some of the Cocoa objects that can use delegates to execute your code:

  • NSTableView. The NSTableView accepts a delegate that obeys the NSTableViewDelegate protocol. This includes 20 to 30 methods that your app’s delegate object can implement to support your app’s need to know what the NSTableView is doing. There are methods that will be called in your application when it needs to know and react to an actions, such as when a user makes a selection in the table or when a column is resized.

  • NSApplication. You can assign an NSApplicationDelegate to handle some of the methods that an NSApplication instance (your application) will receive. These methods may be called just before or just after your application executes another method, so that your app can be prepared.

  • NSWindow. An NSWindowDelegate assigned to one of your application’s windows will give your app a chance to respond to a user resizing, moving, or other window events.

  • NSMenu. You implement an NSMenuDelegate to support events that happen when a user interacts with menus in your application.

Non-Objective-C Frameworks in Macintosh Applications

Apple provides many Macintosh application development frameworks (code libraries) that your app can call to perform the thousands of operations in OS X. Many of these frameworks, such as the PDF Kit, are composed of Objective-C classes, from which your app can create and use objects within your applications. However, some of these frameworks are just libraries of functions that your app can execute.

For instance, the CFNetwork framework is a set of functions that your app can use to perform fine-tuned network connections. The NSURL class provides a good set of basic network operations that are great for retrieving data using a URL. If your app requires more control over the network communications it initiates, you’ll have to use the CFNetwork framework and its functions. You could use the following code to prepare an HTTP request for transmission to a specific URL:

CFStringRef httpBody = CFSTR( "" );
CFStringRef headerFieldName = CFSTR( "Cookie" ); // add specific cookie to HTTP request
CFStringRef headerFieldValue = CFSTR( "loginID=my_user_name; password=my_password;" );
CFStringRef url = CFSTR( "" );
CFURLRef urlRef = CFURLCreateWithStrign( kCFAllocatorDefault, url, NULL );
CFStringRef requestMethod = CFSTR( "GET" );
CFHTTPMessageRef request = CFHTTPMessageCreateRequest( kCFAllocatorDefault, requestMethod, url, kCFHTTPVersion1_1 );
CFHTTPMessageSetBody( request, httpBody );
// add the cookie
CFHTTPMessageSetHeaderFieldValue( request, headerFieldName, headerFieldValue );
CFDataRef serializedHttpRequest = CFHTTPMessageCopySerializedMessage( request );

Once your code has the serialized request, your app can then open a write-stream in order to deliver the request to its destination.

All of the C-based Apple frameworks provide a set of functions for performing this type of lower-level programming. Your code will get more complicated, but Apple doesn't provide Objective-C classes for all its frameworks. If you really require the functionality available in one of those frameworks, this is the only way you can achieve your app’s goals. The following frameworks don't provide Objective-C classes:

  • Audio Toolbox

  • CFNetwork

  • Core MIDI

  • Core Text

  • Directory Service (such as LDAP and Open Directory)

  • Security

If you want to create apps that can take full advantage of the features of OS X, you need to be ready to support the use of non-Objective-C code libraries.

C++ Code in Objective-C Macintosh Applications

Objective-C provides object-oriented features for Macintosh application development, such as inheritance and polymorphism. The language is based on the C programming language; therefore, you can use your C programming knowledge to code within Objective-C. Objective-C++ is a bridge mechanism that allow Objective-C source modules to work with Objective-C++ classes, which could compile and link with C++ code libraries.

The following simple example of a square matrix shows the contents of a C++ header file for a Matrix class. The Matrix class comes with the standard constructor and destructor for a C++ class, and the methods are what you’d expect for a basic square matrix object:

class Matrix
    Matrix( int inSize );
    virtual ~Matrix();
    int getSize( void );
    int getDeterminant( void );
    void setElement( int inRow, int inCol, int inValue );
    int getElement( int inRow, int inCol );
    Matrix operator+( const Matrix& inAddend );
    int m_size;
    int[][] m_elements;

To use Objective-C++, your Objective-C++ class modules must use the file extension .mm. This tells Xcode’s compiler that the class is to be compiled using Objective-C++, which will allow your class to use C++ language keywords. Using Objective-C++, your app could create a Matrix object to perform basic operations, such as adding two Matrix objects together. This assumes the Objective-C++ source module has #imported the C++ Matrix.h file:

- (void)addTwoMatrices
    Matrix matrixOne( 3 ); // 3x3 matrix
    Matrix matrixTwo( 3 ); // another
    int rowIndex = 0;
    int colIndex = 0;
    for (rowIndex=0; rowIndex<3; ++rowIndex)
        for (colIndex=0; colIndex<3; ++colIndex)
            // set matrix one's elements to their values
            matrixOne.setElement( rowIndex, colIndex, XXX );
            // set matrix two's elements to some other values
            matrixTwo.setElement( rowIndex, colIndex, YYY );
    Matrix matrixSum = matrixOne + matrixTwo;

With Objective-C++, your apps are able to take advantage of all the available third-party libraries written for C++.

blog comments powered by Disqus