Sweetening Your Xgrid with Cocoa
Pages: 1, 2, 3, 4, 5
An XGridFoundation Class Overview
To use XGridFoundation, you simply add the framework, which is located in /System/Library/Frameworks, to your Xcode project. In any source file that needs access to XGridFoundation, you import the framework header, like this:
#import <XGridFoundation/XGridFoundation.h>
I want to kick off with an overview of the main players in the XGridFoundation framework. With most Cocoa frameworks (e.g. WebKit), you tend to only use a small portion of the available classes when you are developing an application. With XGridFoundation, you really will need just about all of them, even for something as simple as Central Command. So what follows is an overview of the classes, and what they do. The classes are presented approximately in the order you would encounter them in the flow of a program.
XGConnection- This is used to represent a connection to an Xgrid server. It can be initialized with a host name, or via Bonjour.
XGAuthenticator- In order to open a connection, you will often need a means of authenticating with the Xgrid server, such as a password.
XGAuthenticatoris an abstract class whose subclasses are used by anXGConnectionto authenticate. XGTwoWayRandomAuthenticator- This subclass of
XGAuthenticatorperforms password authentication. XGGSSAuthenticator- This subclass of
XGAuthenticatorauthenticates with Single Sign-On. XGController- Instances of this class are proxies for Xgrid controllers. They are initialized with an
XGConnection, and are used to submit jobs. XGActionMonitor- This class is used to monitor the activity of some asynchronous requests, such as submitting a job via an
XGController. XGResource- This abstract class represents remote-grid resources, like grids and jobs. Instances of subclasses of
XGResourceare proxies for entities on the Xgrid server. XGGrid- This subclass of
XGResourcerepresents grids on the Xgrid controller. XGJob- This subclass of
XGResourcerepresents jobs running on the Xgrid controller. XGFile- This represents a file or stream that is stored on the Xgrid controller.
XGFileDownload- This is a class used to retrieve files and streams from the Xgrid controller after a job is complete.
Putting It All Together
So how do all of these classes work together in a running program? This is one area of the current Xgrid documentation that is severely lacking, so I will try to clarify things here.
As I mentioned earlier, what makes XGridFoundation hard is that everything revolves around networking, and that spells one thing: asynchronicity. To perform just about any operation with XGridFoundation, you have to request it via a method invocation, and then wait for a "callback," which could be a call to a delegate method, but more often than not, is simply a notification arising from key-value observing (KVO). In other words, to know when any stage of the process is complete, you either have to register a delegate, or add an observer with KVO.
To give you an idea of the basic steps involved in writing an Xgrid-enabled application, I am going to list the various operations undertaken by Central Command, in the order that they occur. I will delve into the source code of each step in the coming sections.
- The
runmethod of the application controller class — not to be confused with the Xgrid controller — is called when the user presses the Run button. This method creates anXGTwoWayAuthenticatorwith the password entered by the user, and uses it (together with the host name entered) to initialize anXGConnectionobject. The delegate of theXGConnectionis set to the application controller, and the asynchronousopenmethod ofXGConnectionis invoked. - The
XGConnectiontries to connect to the Xgrid server. If successful, it calls back to its delegate, invokingconnectionDidOpen:. - An
XGControllerinstance is created from theXGConnection. KVO is used to observe thestateattribute of theXGController. - When the
XGControllerstateattribute changes toXGResourceStateAvailable, a job specification dictionary is created, and the job initiated by calling theXGControllermethodperformSubmitJobActionWithJobSpecification:gridIdentifier:. This method returns an instance ofXGActionMonitor; theoutcomeattribute of this action monitor is observed using KVO. - If the
XGActionMonitoroutcomeattribute changes toXGActionMonitorOutcomeSuccess, the job identifier is retrieved from the action monitor'sresultsdictionary. The job identifier is used to retrieve theXGJobinstance that represents the job on the Xgrid controller. TheXGJobis extracted from anXGGridobject, which is retrieved from theXGController. (Got that?XGControllerbegatXGGrid, which begatXGJob.) Thestateattribute of theXGJobis now observed with KVO. (This step is complicated by the fact that at the time that the job identifier becomes available, theXGJobmay not yet have been added to theXGGrid. If this is the case, KVO is used to wait until theXGGridis up-to-date.) - When the
XGJob'sstatechanges toXGResourceStateFinished, theperformGetOutputStreamsActionmethod ofXGJobis called to start retrieving information about the command output. This method returns anXGActionMonitor, and KVO is used to observe itsoutcomeattribute. - When the
outcomeattribute changes toXGActionMonitorOutcomeSuccess, an array ofXGFileobjects is retrieved from theresultsdictionary of theXGActionMonitor. TheseXGFileobjects encapsulate information about the output and error streams. They are used to initializeXGFileDownloadobjects, in order to retrieve the stream data from the Xgrid controller. The downloads' progress is monitored viaXGFileDownloaddelegate methods. - The data of each stream is accumulated during repeated calls to the
XGFileDownloaddelegate methodfileDownload:didReceiveData:. Each download is complete when the delegate methodfileDownloadDidFinish:is invoked.
By now, you are probably wishing you had read the tutorial about building a personal organizer without touching your keyboard. But since your here anyway, why not read on and add to the confusion? In the coming sections I will dissect the steps above, showing you what it all means in Objective-C.

