The following sections provide examples of how to implement the object specifier defined by NSScriptObjectSpecifiers.
An Object Specifier Method for a Rectangle in Sketch
Specifying the Application Object as a Container
Listing 6-1 shows how the Sketch sample application (available from Apple) implements the objectSpecifier method for the SKTGraphic class.
Listing 6-1 An object specifier method for a rectangle
- (NSScriptObjectSpecifier *)objectSpecifier{ |
NSArray *graphics = [[self document] graphics];// 1 |
unsigned index = [graphics indexOfObjectIdenticalTo:self];// 2 |
if (index != NSNotFound) { |
NSScriptObjectSpecifier *containerRef = [[self document] objectSpecifier];// 3 |
return [[[NSIndexSpecifier allocWithZone:[self zone]] |
initWithContainerClassDescription:[containerRef keyClassDescription] |
containerSpecifier:containerRef key:@"graphics" index:index] autorelease];// 4 |
} else { |
return nil;// 5 |
} |
} |
Here’s a description of how this method provides an object specifier for a graphics object. The returned specifier consists of an index specifier for the graphic in its container, and a container specifier for the document that contains the array of graphics:
From its document, it gets the array of graphics and determines the index of the receiving graphic, if it is contained in the array.
It gets the object specifier of the document that contains the graphic.
Sketch defines the SKTDrawDocument class as a subclass of NSDocument. The object specifier method for NSDocument returns an instance of NSNameSpecifier that identifies the document by name within the application's array of ordered documents.
It creates and initializes an index specifier (type NSIndexSpecifier) for the receiving graphic and returns it.
The specifier locates the graphic by index within the graphics in its document. Although an AppleScript script asks for indexed items as though they are one-based, this index specifier, which locates objects within an array that correspond to the specified items, works with zero-based values. For information about the other parameters, see “About Object Specifier Classes.”
To specify the application object as the top-level container for a specifier, you can use code like the following. This snippet is part of the document class and obtains an object specifier for the document by name (rather than by index, which may become invalid if the document ordering changes):
Listing 6-2 Specifying the application as a container
NSScriptClassDescription *containerClassDesc = (NSScriptClassDescription *) |
[NSScriptClassDescription classDescriptionForClass:[NSApp class]];// 1 |
return [[[NSNameSpecifier alloc] |
initWithContainerClassDescription:containerClassDesc |
containerSpecifier:nil key:@"orderedDocuments" |
name:[self lastComponentOfFileName]] autorelease];// 2 |
Here’s a description of what this code snippet does:
The application is the container for a list of ordered documents, so this code first obtains a class description from the global application object, NSApp. (You never pass nil for the class description.)
It then creates and returns an autoreleased object specifier of type NSNameSpecifier, passing nil for the containerSpecifier parameter to specify the top-level container, the application. (This is the only case in which you can pass nil for the container.)
It invokes the NSDocument method lastComponentOfFileName to obtain the name of the document and uses it to construct a name specifier object.
Last updated: 2008-03-11