Table of Contents Previous Section

Notes for Objective-C Developers

As explained at the beginning of the tutorial, you can write your application's logic using Java, Objective-C, WebScript, or a combination of WebScript and Objective-C. If you choose Java, you must write the entire application in Java. If you choose Objective-C, you can write part of the application in WebScript. Often, you would choose to write custom business logic in Objective-C and write component logic in WebScript.

The following sections describe the differences between developing applications in Objective-C and developing applications in Java.

Creating an Objective-C project

To create an Objective-C application, simply create a new project in Project Builder of type WebObjectsApplication. Project Builder creates the directory with the .woa extension and adds Application.wos, Session.wos, and Main.wo to it as well as the makefiles and other supporting files. After you create the Project Builder project, you can open the .woa directory in WebObjects Builder-it's not necessary to create the project in both WebObjects Builder and Project Builder.

Objective-C main function

If you create an Objective-C project in Project Builder, main is provided as a C function in the file main.m:

void main (int argc, const char *argv[])
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	WOApplication *application = [[[WOApplication alloc] init] 
		autorelease];

	[application run];

	[pool release];
	exit(0);
}
#ifdef WIN32
#import <EOAccess/EOAccess.h>

void _referenceEOFrameworks()
{
	static id a;
	a = [EOEntity new];          // EOAccess
}
#endif
The main() function begins by creating an autorelease pool that's used for the automatic deallocation of objects that receive the autorelease message. Next, it creates the WebObjects application object and starts the request-response loop. The last statement releases the autorelease pool, which sends a release message to any object that has been added to the pool since the application began.

If you're setting up a project by hand and you intend to run the application on the Windows NT platform, you must include the _referenceEOFrameworks() function as well. This function makes sure the Enterprise Objects DLLs are loaded at the appropriate time.

Note: If you're setting up a project by hand, you'll need to add the link line to the makefile youself. For example:

/bin/cc -o executableName  -LobjectFiles -framework WebObjects 
-framework Foundation
Be sure to link to the WebObjects framework before the Foundation framework.

On the Solaris platform, you also need to link to the framework NextLibrary/PrivateFrameworks/MultiScript.framework. If you use the provided makefiles, this is set up for you.

Subclassing WebObjects classes

If you subclass WOApplication or WOSession, name the subclass Application or Session, respectively. If you follow this naming convention, you are able to add further functionality to your object in Application.wos or Session.wos. If you name your subclass something else, you shouldn't implement Application.wos or Session.wos.

Accessing compiled code from a script

Accessing compiled code from a script is simply a matter of getting an object of the compiled class and sending it a message. For example, if you implemented Registration's Main component in WebScript, you'd write the following line to instantiate a Person object:

/* Return a Person object by invoking Person's 
      personWithDictionary: method */
aPerson = [Person personWithDictionary:newPerson]; 

Accessing script methods from compiled code

To access a scripted object's methods from compiled code, you simply get the object that implements the method and send it a message. If you're accessing a method in the application or session script, you can use WOApplication methods to access the object:

[[WOApplication application] applicationScriptMethod];
[[[WOApplication application] session] sessionScriptMethod];
To access a component's methods, you must store the component in the session and then access it through the session.

For example, suppose you wanted to rewrite the Registration application so that Person's validate method directly sets the value of the message variable in the Main component. You'd add the following statement to the init method Main.wos:

/* Store the component in the session. */
[self.session setObject:self forKey:@"Main"];
and then you can access it in Person's validate method this way:

/* Get the component from the session: */
WOComponent *mainPage = [[[WOApplication application] session] 
objectForKey:@"Main"];
/* Send it a message */ [mainPage setMessage:@"You must supply a name and address"];
(Main.wos implicitly implements the setMessage: method because it declares a variable named message.)

To avoid compiler warnings, you should declare the scripted method you want to invoke in your code. This is because scripted objects don't declare methods-their methods are parsed from the script at run time. If you don't declare their methods in your code, the compiler issues a warning that the methods aren't part of the receiver's interface.

Note: This step isn't strictly required-your code will still build, you'll just get warnings.

For the example above, you'd add the following declaration to the Person.m file:

@interface WOComponent (RegistrationMainComponent)
- (void)setMessage:(NSString *)aMessage;
@end
While it's certainly straightforward to access a scripted object's methods from compiled code, you may not want to have that degree of interdependence between your scripts and your compiled code. You may want to minimize the interdependence to facilitate reusability.

Using C and C++ in WebObjects applications

In addition to using compiled Objective-C in WebObjects applications, you can also use compiled C or C++. The interface you provide to WebObjects must be in Objective-C because WebObjects can't invoke C or C++ functions. However, you can directly invoke C and C++ functions from Objective-C.

Some of the options for integrating C or C++ code into your application are as follows: