Developer --\> Technical Publications
PATH  Mac OS X Server Documentation > Making Your Applications Scriptable

Making Your Applications Scriptable

Previous | Chapter contents | Next | Book PDF

Make Objects Responsive to Key-Value Coding

Overview

Key-value coding is a set of APIs that establishes a generic and automatic mechanism for setting and getting the properties of objects. It enables you to access object properties indirectly--and consistently--by property name (or "key") rather than through the invocation of a method or directly getting or setting an instance variable.

Key-value coding is based on two primitive instance methods of NSObject: valueForKey: and takeValue:forKey: . These methods are implemented to look first for the accessor methods corresponding to the key. For example, [valueForKey:filter] attempts to use accessor method filter ; the message [takeValue:anObj forKey:filter] attempts to use accessor method setFilter: If an accessor method doesn't exist, key-value coding attempts to get or set the value of the instance variable directly.

Keys are of three general types relative to the type of associated value: attribute, one-to-one relationship, and one-to-many relationship. A typical attribute key might be "color," a window's "document" key is a typical one-to-one relationship key, and a common one-to-many relationship is identified by an application's "orderedWindows" key. In AppleScript, "property" refers to the same thing as an attribute and "element" refers to a relationship.

The Yellow Box scripting classes use key-value coding to return and set the attributes and relationships of objects. They also use it to evaluate "object specifiers." AppleScript has the notion of "object hierarchies" that define the structure of the objects of an application. It uses object specifiers (object representations of AppleScript reference forms) to navigate through this hierarchy to a particular object (for example, "word 5 of paragraph 2 of the front document"). The evaluation of object specifiers is necessary to find the receivers (or targets) of commands and frequently their arguments.

What You Must Do

To let your application take advantage of key-value coding, you should do the following:

As an illustration, assume you have a DrawingCanvas object that you want to make scriptable. In a simple scenario, you want scripts to be able to access (and modify, if necessary) the graphical shapes of that object, and you also want scripts to be able to access and set the currently selected shape. To this end, you define two keys, "shapes" and "selectedShape". These become instance variables of the DrawingCanvas class:

@interface DrawingCanvas: NSObject <NSCoding> {
	NSArray *shapes;
	NSBezierPath *selectedShape;
	// ...

Next implement accessor methods for these instance variables:

- (NSArray *)shapes {
	return shapes;
}

- (void)setShapes:(NSArray *)newShapes {
	[shapes autorelease];
	shapes = [newShapes retain];
}

- (NSBezierPath *)selectedShape {
	return selectedShape;
}

- (void)setSelectedShape:(NSBezierPath *)newShape{
	[selectedShape autorelease];
	selectedShape = [newShape copy];
}

The next step is to specify the keys "shapes" and "selectedShape" in the formal description of the DrawingCanvas class. This class description is in the suite definition you must create for any class with unique attributes, relationships, or commands (see " Create a Suite Definition and Suite Terminologies " for further information). The "selectedShape" key is an one-to-one relationship key; the "shapes" key is a one-to-many relationship. The relevant section of the class-description property list might read as follows (the Apple Event codes, of course, are made up for this example):


 
"DrawingCanvas" = {
	"ToOneRelationships" = {
		"selectedShape" = {
		    "Type" = "NSBezierPath";
		    "AppleEventCode" = "abcd";
		    "ReadOnly" = "NO";
		 ;};
	  };
	"ToManyRelationships" = {
		"shapes" = {
		    "Type" = "NSArray";
		    "AppleEventCode" = "efgh";
		    "ReadOnly" = "NO";
		};
	(and so forth)

Making Your Applications Scriptable

Previous | Chapter contents | Next | Book PDF