TweetFollow Us on Twitter

AppleScript in Cocoa

Volume Number: 18 (2002)
Issue Number: 05
Column Tag: AppleScript in Cocoa

It's Now Easier to Support AppleScript Suites in Cocoa

by Don Briggs donbriggs@mac.com

AppleScript Studio is now available to developers. This product will open Mac OS X development to many more people, and they will build applications relying on AppleScript. If their applications are to interoperate with yours, your Cocoa applications and their underlying frameworks must also support AppleScript.

This article is for Cocoa Objective-C developers. It will review the concepts and techniques necessary to implement AppleScript support. It will show the steps necessary to revise an existing example to support AppleScript. It introduces a new application for composing AppleScript suites —SuiteModeler. A compressed disk image

EZCocoaAppleScript.dmg.gz is available for download at: http://homepage.mac.com/donbriggs/FileSharing.html

The disk image contains:

  • this document as EZCocoaAppleScript.rtfd;
  • KVC_Demo —a simple Project Builder tool project that demonstrates Key-Value Coding;
  • DotSuite.scriptDocument, a SuiteModeler document (a wrapper/directory) containing the suite definition and suite terminology files for a Cocoa AppleScript suite, and a directory of ‘naive' Objective-C files to support the suite.
  • ScriptableDotView —the example application we will build in this article as a Project Builder project;
  • sample output documents (bigRed.dot, littleBlue.dot) in XML form; and
  • a test script that drives our ScriptableDotView application.

Overview

In this article, we will compose an AppleScript suite from scratch using SuiteModeler. This suite will serve as a statement of requirements, and the Objective-C files that SuiteModeler emits will serve as a starting point for our implementation. From these Objective-C files we will implement the classes and commands of the suite. We will build the document-based application, ScriptableDotView, that supports the suite. To emphasize KVC, we will also employ it to provide XML persistence for our documents in just a few lines of code. We will repackage the data-handling classes of our suite as a reusable framework. Finally, we will test our implementation using AppleScript.

Introducing SuiteModeler

The reader is invited to download SuiteModeler version 1.7.2 (or later) and run it in Demo mode. You need not buy a license to follow this article —the disk image provides all the required output files. SuiteModeler's Demo mode also permits you to inspect other suites and to check them for conflicts (see below). In licensed mode, SuiteModeler will save the suites you compose.

Suites were Hard to Compose

Nominally we use Apple's "PropertyList Editor" application

file:///Developer/Applications/PropertyListEditor.app

to compose Cocoa suites. It supports the property list format, but the following difficulties remain:

We need to produce two files, the *.suiteScript and *.scriptTerminology. Each provides its own "projection" of the underlying classes, but these projections are not "orthogonal"—the two files must maintain a nontrivial correspondence. But "PropertyList Editor" edits each file separately.

There are lots of key words, and their values must obey rules. You must read and apply

file:///Developer/Documentation/Cocoa/ProgrammingTopics/Scripting

Some symbols refer to others, but unresolved references are not immediately obvious.

There are some annoying or confusing aspects of the Cocoa documentation: we find two meanings for the word "Property," for instance.

Some entries are generic and could be "calculated" from others, but "PropertyList Editor" does not provide such help —it's a general application.

Finally, when inspecting a suite (or rather, one half of a suite) in "PropertyList Editor," much of the text we see amounts to repeated key words.

In short, we could use some better tooling.

Suites were Hard to Support

Given a composed suite, the developer hoping to support AppleScript in Cocoa must make sure the Objective-C classes correspond to the suite. In the phrase often used by College-level Math texts, the process is "tedious but straight-forward." And "by inspection" —those same texts also say "by inspection" a lot. Admittedly, your second suite will be much easier, but your first one will require close reading of several lengthy documents. Wouldn't it be nice if your first suite were easy and it "just worked"?

Suites were Hard to Debug — Conflicts!

Even after a script compiles, it may not run as expected; the trouble often lies in the relationships of Apple Event Codes and external names. A given code can associate with multiple external names, but a given external name must associate with a unique code. If your suite matches an Apple Event Code with an external name that already exists in another suite loaded at run-time (NSCoreSuite and NSTextSuite come to mind), scripts written against your suite may crash or yield unexpected results. Such conflicts have stumped experts —and for good reason. To the author's present knowledge, this "gotcha" remains undocumented by Apple. (Greg Titus of OmniGroup for pointed out this "gotcha" to the author. Thanks, Greg.)

Composing and Supporting Cocoa Suites Just Got Easier

SuiteModeler is available as a demo at http://homepage.mac.com/donbriggs/FileSharing.html

You are invited to download it and use it to inspect Cocoa suites. The download site provides a screenshot of the suite from the Create application from Stone Design.

The Cocoa suites you compose will often build on NSCoreSuite and NSTextSuite. You'll find these among SuiteModeler's "Open Recent" menu items. When using SuiteModeler to inspect a suite or check one for conflicts, be sure to open any suites it depends on.

Background on AppleScript in Cocoa

To implement AppleScript support in Cocoa, you need to know about two important supporting concepts —the design pattern known as Model-View-Controller (MVC), and the technique known as Key-Value Coding (KVC). If you have not seen these Cocoa documents before,

file:///Developer/Documentation/Cocoa/ProgrammingTopics/AppDesign/AppDesign.1.html

file:///Developer/Documentation/Cocoa/TasksAndConcepts/ProgrammingTopics/KeyValueCoding/index.html

this article will introduce you to the main ideas we need to understand to support AppleScript. We also need to focus on document-based applications as described in

file:///Developer/Documentation/Cocoa/ProgrammingTopics/AppDesign/AppDesign.d.html

You will find that when we use NSApplication and NSDocument, we get lots of AppleScript support for free.

Regular readers of MacTech and those long interested in AppleScript for Cocoa already know of Andrew Stone's earlier article, "Adding AppleScript Support to Cocoa Apps." http://www.mactech.com/articles/mactech/Vol.16/16.07/AppleScripttoCocoa/

There, Andrew discussed MVC, KVC, and AppleScript support in the Sketch example. Andrew's article also showed us how to add a "Save as AppleScript..." capability to Sketch.

Sketch is quite a large example, and presents its AppleScript suite with little explanation. A reader previously unfamiliar with Sketch might find it daunting. This article takes a bare-bones approach to building a suite —the ratio of explanation to code is quite different. We start from a simpler example, DotView, which is found at file:///Developer/Examples/AppKit/DotView.

Newcomers might compare DotView and Sketch for size and complexity, then take a relaxing deep breath.

Model-View-Controller — MVC

The Model-View-Controller design pattern comes to us from the Smalltalk tradition. MVC suggests that we partition our objects into those that treat the "real data" —the "Model" part; those that provide a human interface to the data —the "View"; and other stuff necessary to glue the Model and View together —the "Controller" part.

Generally, design patterns identify commonly occurring archetypes of interoperating components. They bear "prior knowledge" at the conceptual and architectural level. The main benefit of following the MVC design pattern is the reusability of the components we build.

The Cocoa frameworks were designed to support MVC. Using Cocoa, we find we can often make the "Model" part into a stand-alone framework and use it again for other purposes. Our "Model" frameworks commonly build on the Foundation framework —Foundation comprises mostly "Model" classes that encapsulate "real data." The AppKit framework provides classes that support the "View" and "Controller" parts. Often, we can get most or all the "View" part from Interface Builder. For ScriptableDotView, Cocoa provides much of the Controller part with no extra code. If you avoid storing "model" information in "view" objects (for instance, don't store a boolean in a button's state), you'll find that the Cocoa frameworks provide a natural basis for the MVC design pattern. When we add AppleScript capability, we add a powerful way to control the "Model" part.

Key-Value Coding —KVC

Key-Value Coding amounts a simple discipline that matches the declaration of an instance variable to the declarations of its getter and setter methods. When we follow those rules in a class for an instance variable, we implement KVC in that class for that variable. Given an instance variable of primitive type ( BOOL, char, short, unichar, int, float, double, ...) or struct (NSRange, NSPoint, NSSIze, NSRect, ... ) we have as a declaration

   type _xyz;    // Let type be one of: 
      // BOOL, char, short, unichar, int, float, double, ..., NSRange, NSPoint, NSSIze,             
      // NSRect, ... and as accessors
   -(type)xyz;
   -(void)setXyz: (type)xyz;

Given an instance variable that is an object, we have as a declaration

   MyClass *_abc;
and as accessors
   -(MyClass*)abc;
   -(void)setAbc: (MyClass*)abc;

You may neglect the underscore prefix in the name of the instance variable, but then you should change the name of the argument in the corresponding setter method.

The KVC_Demo project is a simple one-class tool project that shows KVC at work. You can use KVC to reduce the complexity of your code, independent of AppleScript support. The Cocoa documentation on scripting recommends that you "define the set of keys each scriptable class supports." The author suggests that you use class methods to provide collections of related keys. In KVC_Demo, the class method +[ModelClass kvcKeys] provides such an array of keys.

DotView Revisited

Copy the example DotView project to a convenient place, compile it, run it, and marvel at it. The DotView example application shows us how a subclass of NSView can respond to a mouse click with a drawing operation. The project has a single class, DotView—pristine simplicity. But with apologies to DotView's author, Professor Ozer*, the author points out that DotView does not follow MVC nor does it support KVC. Newcomers might breathe a sigh of relief now. If presently your code falls short too, you'll find yourselves in fine company.

(*Ali Ozer only professes to be the head of the AppKit —he is the only remaining original engineer from the first four that worked on NeXTSTEP in the late eighties.)

Consider the class DotView from the perspective of MVC. It descends from NSView but has instance variables and accessor methods for the only "real data" of the application. It's both the "View" and the "Model." DotView has no need for a "Controller" part, then. We'll revise the project along the lines of MVC.

As for KVC, we see that there are instance variables named "color" and "radius" with the accessors

   - (IBAction)setRadius:(id)sender;
   - (IBAction)setColor:(id)sender;

But these method signatures do not support KVC —each "setter" method should take as its single argument a variable of the same type as its associated instance variable. To support KVC, we need instead

   -(float)radius;
   -(void)setRadius: (float)radius;
and
   -(NSColor*)color;
   -(void)setColor: (NSColor*)color;
We'll fix that, too.

On to ScriptableDotView.app

Let us imagine that we work as developers for the company called "My Great Software, Inc." and that the prototype application, DotView, has successfully promoted an idea for a marketable application. Marketing loves it, Management is committed to it, and now we have to deliver on its promise. ScriptableDotView will be our product, an industrial-strength revision of the prototype. A high-level meeting has produced a set of requirements. (We always need requirements. How else will we know when we're done?)

Requirements

    [0] ScriptableDotView reproduces the look and feel of DotView.

    [1] ScriptableDotView has just one kind of document, and it saves the state of a "Dot" —its radius, position, and color.

    [2] The document must persist in XML form. Management loves buzz-word compliance. (XML really is useful, though.)

    [3] The document must permit AppleScript access to its dot's radius, position, and color.

    [4] The document must support an AppleScript command, ReCenter, to place the dot in the center of the view area.

    [5] And Marketing suspects that a few other related applications could follow on, so we should encapsulate the "real data" in a framework that we can use again.

An Internal Requirement

The ReCenter command is the simplest kind of command; it takes no arguments and returns void. While we're exploring AppleScript support, it seems prudent to demonstrate support for a command that takes an argument and returns a value. We'll add a command to the Dot class that does something simple and clearly useless to ScriptableDotView: it will take a string argument and return a string with the same characters in the opposite order. We'll spend just a few minutes under Management's radar on this, but this exercise will improve our confidence in supporting AppleScript. We add to our requirements:

    [6] The Dot class will temporarily support the Reverse command (a command with one argument and a return value).

Design Overview

At the core of things, we have the concept of the dot, the "real data" of the application—the "Model" in an abstract sense. We'll have a class, Dot, to manage the dot's radius, position, and color. Also, we'll have a subclass of NSDocument, DotDocument, to manage a single instance of Dot. The separation between the dot and its document may seem contrived, but often a document manages a collection of model objects, but here, we have just the single element. (Often, a descendent of NSDocument acts as a sort of Model-Controller. Contrast this to NSWindowController, which is a kind of View-Controller.) As for the rest of the "Controller" part, we could conceivably subclass NSDocumentController and NSWindowController, but for the sake of expediency, we'll force into the DotDocument class any leftover model-controller methods we need. We'll package the Dot and DotDocument classes in a scriptable framework, , to provide the "Model" and "Controller" parts of our MVC design. The "View" part must derive from the prototype to preserve its look and feel. Here, this means that we can copy the *.nib file of the prototype and make a few modifications. As a novel departure, we will start with an AppleScript suite as a statement of requirements and then drive the implementation to support our suite.

DotSuite

Our suite, DotSuite is conceptually very simple: it has two classes: an instance of the DotDocument class serves as a container for an instance of the Dot class. DotDocument has just one read-only attribute, its dot. Dot has four attributes: its x and y positions, its radius and its color. DotSuite has the two Commands, but no Enumerations or Synonyms.

Ideally, Dot should have one attribute of type NSPoint instead of two attributes of type float, the x and y positions. However, as presently documented, Cocoa AppleScript suites support only primitives (BOOL, short, int, float, ...) and objects as attributes. We look forward to support for structs such as NSPoint and NSRect. Curiously, if you examine NSCoreSuite, you'll find a dictionary called ValueTypes with one entry pairing the key QDRect with the string value qdrt. Also, the NSWindow class has a property named boundsAsQDRect and type NSData. As of Mac OS 10.1.3, the author has found no documentation explaining these entries. We'll follow the lead of the Sketch example and proceed with the pair of floats (as instances of NSNumber).

The AppleScript Suite —DotSuite

To compose this suite, launch SuiteModeler and edit its empty suite document. The screen shots below show what to type in. In the "Preferences" panel, choose the "Cocoa/E-R/EOModeler" nomenclature to see these tab labels. SuiteModeler combines the definition and terminology in one document and presents it as a tree of table views. Wherever a node has multiple children, the children appear as tabs in a tab view. The root of the tree, the suite itself, is a special case and appears as a the "Suite" tab among its children. Also, an extra "Summary" tab provides a flattened summary, useful for sorting out more complicated suites and finding conflicts.

The Suite Itself

The suite itself has an internal and an external name, an Apple Event code, and a description. Fill in these four fields as shown. (Throughout this exercise, we will neglect entries in the description fields. SuiteModeler makes it easy to add them, and they can be extremely useful to the AppleScript authors who will incorporate your application in their scripts. However, descriptions are the least of our immediate concerns.)

pastedGraphic.tiff 

Apple Event code entries always have four characters, and SuiteModeler enforces that constraint. Apple has reserved the space of codes comprising all combinations of four lower-case letters, so always use at least one upper-case letter in your codes. (Beware: if the trailing characters are spaces, that fact won't be apparent in "PropertyList Editor" unless you select the entry.)

Commands

We start with the two Commands. In the "Commands" tab, use the upper "+" button to add thwo entries. Their names appear initially as MyCommand, and MyCommand_1. Enter the values for the fields in the upper table as shown (use any string for the descriptions). Rename them and enter the other fields as shown. Notice that SuiteModeler generates some fields for you: given a name, it guesses the external name. Given an external name, it guesses the plural and sometimes, it can correctly guess the appropriate Apple Event Code value.

1__#$!@%!#__pastedGraphic.tiff 

The ReCenter command takes no arguments and yields no result. It simply re-centers the dot in the view and serves as an example of the simplest kind of command. With the Reverse command selected, use the "+" button in the lower table to add its string argument as shown. The Reverse takes a string as an argument and returns a string of the same characters in the opposite order (just to demonstrate an AppleScript command with an argument and a return value).

Classes

Our suite has two classes. In the "Classes" tab, use the upper "+" button to add two entries. They appear with MyClass and MyClass_1 in the "name" column, again with default entries in the other columns.

The DotDocument Class

In the first entry, type in DotDocument in the "name" column. SuiteModeler generates its external name and plural, so these entries are in gray. Type in docu for its Apple Event Code, and NSCoreSuite.NSDocument as its superclass. Here, we're using the code docu from the core suite, so it's all lower-case. The superclass entry appears in red denoting an unresolved reference. (To resolve the reference, open the NSCoreSuite from the "Open Recent" menu. This entry then appears in black.) Type in an entry for the description. With the DotDocument row still selected, choose the "Attributes" tab in the lower half of the split view. Then use the lower "+" button to add an attribute. Set its name to dot, its type to Dot, its code to xDot, and set the "[r/o]" or Read-Only column entry to Y or y. SuiteModeler will complete the entry. SuiteModeler constrains the entries for the sex and number columns in a similar way —just type in the first letter of your choice.

The Dot Class

The entries for the Dot class follow from the screen shot. (Once you've typed in its name, the reference to it in the DotDocument class should appear in black.) Notice that its external name, dot, appears in blue (multiple references), and its code, xDot, appears in grey (default) to indicate that all (here, both) items with the same external name have the same code.

2__#$!@%!#__pastedGraphic.tiff 

3__#$!@%!#__pastedGraphic.tiff 

Tying Classes to Commands

For each of the two classes, add supported commands as shown. Had we not defined these commands first in the "Commands" tab, their names would have appeared in red—perhaps a little alarming for an introduction. Again, given the name for a supported command, SuiteModeler calculates a method name.

4__#$!@%!#__pastedGraphic.tiff 
5__#$!@%!#__pastedGraphic.tiff 

Tool Tips

The headers of the columns of all the table views in SuiteModeler provide tool tip support. Each column's tool tip associates a key with the text from the corresponding tables of the documentation in

file:///Developer/Documentation/Cocoa/ProgrammingTopics/Scripting/SuiteDefs

The exception is the "ext. name" column. It shows the synthetic "HumanReadableName" instead of "Name," which is the key associated with the "name" column.

Conflicts —a Demonstration

As an experiment, temporarily make a conflict of codes and external names. Change the code for the dot class from xDot to yDot then switch to the "Summary" tab. You'll see that suddenly the codes and external names involved in the conflict appear in red. If you try to save the suite document in such a state, SuiteModeler will warn you. Change it back to xDot.

6__#$!@%!#__pastedGraphic.tiff 

Some readers may choose to complete this exercise successfully, then build in a conflict and explore the consequences.

Save

If you've not bought a license, use the result supplied. Otherwise, save the result as DotSuite, using the default choice, document wrapper, for the output file format. The wrapper contains the definition and terminology files. Check it against the version supplied.

You could also reproduce the work in the "PropertyList Editor" application, but you'll have to read the documentation more carefully to produce a working suite that way. Choose a non-trivial existing suite, say NSCoreSuite to compare SuiteModeler and "PropertyList Editor." You'll find the SuiteModeler presentation more compact and unified (after all —using "PropertyList Editor," you have to open two documents, the definition and the terminology). Certainly, when you compose your own suite, SuiteModeler's validation, automatic generation of default values, and cross-referencing features will save you some headaches.

The ‘Naive' Objective-C Files

SuiteModeler also emits a directory of Objective-C files when it saves a suite document. Open all the Objective-C files in the document wrapper now. Each class in your suite results in a *.h and a *.m file. A single *.h file declares any enumerations in the suite. For each class, it provides instance variables and accessors for each attribute/property and property/element (only the "getter" methods for the read-only cases). It also declares and provides a base implementation for each supported command, declaring and extracting any command arguments. It also declares and implements a class method that provides an array of keys useful for KVC. It also provides some support for object specifier methods.

Implementation —Step by Step

SuiteModeler will not emit all the code necessary to implement your suite, and the class files will likely not compile as emitted. In each case, you'll need to add or modify a few lines to import the parent class, and to import or declare any other classes referenced (perhaps using "@class" in the *h files). You may need to import these from your own frameworks. However, SuiteModeler has saved you lots of typing. As a developer, you must provide the underlying logic specific to your "Model" —that's why "My Great Software, Inc." pays you the big bucks. For each class, Dot and DotDocument, we explain the few lines we modify to compile the naive file. Then we add categories of "Model" logic to each.

First we'll build and test a simple application. Then we will repackage it by moving two classes into a framework. We will also make the framework scriptable. We'll re-compile and test the repackaged code. Then we'll drive the resulting compiled application with an AppleScript suite.

Start with a Cocoa Document-based project. It provides a generic "MyDocument" class—keep it. Add the Dot and DotDocument files to the "Classes" group, "by copy" from the suite document wrapper. We'll move them into a framework later. For the methods below, find their implementations in the completed project.

In this exercise, we will rely on several categories in separate files. A category encapsulates a group of related methods. The author hopes that by isolating these categories in separate files, the reader will find it easier to track differences using FileMerge. (The XML methods for NSDictionary can prove generally useful.) Otherwise, this exercise takes the notion of categories and protocols perhaps a bit too far.

Initial Details —Imports and Declarations

    [1] In Dot.h, add

       @class DotDocument;
    

    just before the "@interface ..." line.

    [2] In DotDocument.h, comment out the line

       #import "NSDocument.h" 
    

    We get reference to that class when we import the <Cocoa> framework.

    [3] Also in DotDocument.h, add

       @class Dot;
    

    just before the "@interface ..." line.

    [4] In DotDocument.m, import the Dot class. Add

       #import "Dot.h"
    

    just after the existing import.

    [5] in Dot.m, import DotDocument.h similarly.

The changes so far should permit you to compile the ‘naive' files, but the compiler will warn about unused variables.

Add a Category of XML Methods to NSDictionary

Add to your projects by copy the files NSDictionary+XMLMethods.h and *m (provided in the ScriptableDotView project). You may find this category generally useful. See Brian Webster's post on the OmniGroup Cocoa Dev list, www.omnigroup.com/mailman/archive/macosx-dev/2001-January/008625.html

One might reasonably expect Cocoa API for this. As things stand, we drop down into Carbon.

Repackage the MyDocument Methods as a Category

Project Builder provides some Objective-C code in the generic "MyDocument" class. Convert the MyDocument class to be the DotDocument+Subclassing category. Rename the *.h and *m files, change the import statement in the *.m file, and change the @interface and @implementation lines to support the category. They become

   @interface DotDocument (Subclassing) 

and

   @implementation DotDocument (Subclassing)

(and delete the pair of curly braces in the *.h file). Also in the *.m file, change the windowNibName method to return @"DotDocument".

Augment DotDocument+Subclassing For XML Persistence

In the *.m file, import NSDictionary+XMLMethods.h and Dot.h. In the methods

   dataRepresentationOfType:

and

   loadDataRepresentation:ofType:

add the few lines necessary to provide XML persistence. Notice that KVC makes this really compact. Compare with SKTDrawDocument in the Sketch example. Sketch resorts to the methods -[SKTGraphic propertyListRepresentation] and +[SKTGraphic graphicWithPropertyListRepresentation] and their overriding implementations in the subclasses of SKTGraphic. If we had comparable subclasses here, we would only need to override the +kvcKeys method in each subclass (assuming we had already written the matching get and set methods anyway). Remember that any code you don't have to write is code you don't have to debug, either.

Add DotDocument+ModelControlling as a Category

This category comprises two methods. One writes "Model" information to the "View," and the other writes "View" information to "Model." Such a pair of methods often proves useful. Import the DotDocument+ModelControlling.h category.

Add the NSView+DotViewing Protocol

This protocol declares one method. It will become part of the framework. The application will have a DotView class that conforms to it.

Add Model-Controller Instance Variables and Logic to DotDocument

In DotDocument.h add these instance variables

   IBOutlet NSView *_view;
   IBOutlet NSSlider *_slider;
   IBOutlet NSColorWell *_colorWell;

and declare these methods:

   -(IBAction)viewAction: (id)sender;
   -(void)modelChanged;

The viewAction method responds to user interactions—mouse clicks and drags, and setting the color—and passes the information to the document, which sends it to the model. The modelChanged method signals the "View" that it must re-draw to reflect changes in the "Model." In Document.m, import the DotDocument+ModelControlling.h category. It comprises two methods. One writes "Model" information to the "View," and the other writes "View" information to the "Model." In this class, they're both empty—we'll override them in DotDocument to do useful work. Add the awakeFromNib method to initialize the "View." Find the implementations for these methods in the completed project. Add an init method that initializes the document's instance of the Dot class. Add the awakeFromNib method to initialize the "View."

Augment the Class Implementations with Custom "Model Logic"

Declare and implement the initWithDocument: method, and import "DotDocument.h". DotDocument's handleReCenterScriptCommand: and Dot's handleReverseScriptCommand: both require few-liner modifications. We can't save NSColor in property list form directly. As in the Sketch example, we'll have to archive NSColor as NSData. We're not free to replace the naive color accessors —AppleScript needs them—so we'll supply two more to access the color attribute as archived NSData. Be sure to change colorKey to colorDataKey so our kvcKeys method can support XML persistence. We'll come to the remaining new instance variable and the initializer later.

Steal Your Interface

Open the MainMenu.nib document of the DotView example and copy its Window component (it has the view, color well, and slider). Open your project's MyDocument.nib file, delete its Window component and replace it with the one from DotView. Drag the DotDocument.h file from Project Builder's files pane onto the MyDocument panel, so Interface Builder can parse the file. Set the File's Owner to be DotDocument. Delete MyDocument from your nib. Disconnect the actions for the slider and color well, and connect them to the File's Owner, choosing the viewAction: method. Save the result as DotDocument.nib.

Adjustments for Fit and Finish

Choose your project's "Targets" tab. In the "Application Settings" tab and using the "Expert" settings, set the document class to be DotDocument and set the file extension to be dot. Choose the "simple" settings and set the document's extension to dot.

First Test

The application should compile and launch after you have made these changes. It should be able to save and open its documents in XML form.

Make it Scriptable

Under the application target's application settings tab, choose the "expert" settings and add a new sibling called NSAppleScriptEnabled. Set its value to the string YES. Add to the Resources group the files DotSuite.scriptSuite and DotSuite.scriptTerminology from the DotSuite.suiteDocument file wrapper provided, using the "by copy" option. Localize the terminology file (select it in the Files pane and "Show Info"). Be sure that these files are checked as part of the application target. Recompile. Now, Script Editor should be able to browse to your project's "build" directory and open your application's dictionary. Also, the script provided should properly drive your application.

One More Step —Repackage the "Model" classes as a Framework

Refer to the article http://www.cocoadevcentral.com/tutorials/

"Frameworks Within the App Bundle" by Brian Christiansen, Cocoa Dev Central

Following the article, set the framework's installation location to the path:

   @executable_path/../Frameworks

and add the linker flag

   -seg1addr 0x10000000

as detailed there.

From the "Project" menu, choose "new target." Choose its type to be Cocoa framework. Set the name of the framework target to be Dot. In the Target pane, set the Dot target to be ‘under' ScriptableDotView (that is, to make ScriptableDotView, you must first have made Dot. )

In the File pane, add a new Group called and select it. Move the NSView+DotViewing protocol and the Dot and DotDocument classes into the new group. Remove them from the application target and add them to the framework target. Be sure to set those headers to "Public." Similarly, move the DotSuite.scriptSuite and DotSuite.scriptTerminology files to the framework. You'll also need to drag the Dot.framework element in the "Products" group in the Files pane to the application target's "Files & Build Phases" tab's "Frameworks & Libraries" fields.

QED

Compile and run the application. If it fails, compare your project against the supplied ScriptableDotView project. You should be able to verify that the requirements have been met.

Conclusion

We've used the SuiteModeler application to compose a Cocoa AppleScript suite as an expression of requirements. We've developed a framework and application on it that support our AppleScript suite, starting from the Objective-C files SuiteModeler emitted, adjusting only the imports and declares, and adding just a few lines of "Model" logic. We have used Key-Value Coding both in the support of our suite and to simplify XML persistence of our document-based application. We have used AppleScript to test our implementation. Readers can now build their own script-enabled Cocoa applications and frameworks more easily.


 
AAPL
$94.24
Apple Inc.
+0.30
MSFT
$44.91
Microsoft Corpora
+0.08
GOOG
$597.95
Google Inc.
+8.48

MacTech Search:
Community Search:

Software Updates via MacUpdate

MacBook Air EFI Firmware Update 2.9 - Fo...
MacBook Air EFI Firmware Update is recommended for MacBook Air (Mid 2011) models. This update addresses an issue where systems may take longer to wake from sleep than expected and fixes a rare issue... Read more
FileZilla 3.9.0.1 - Fast and reliable FT...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface.Version 3.9.0.1: MSW: Fix installation issue with locked DLLs... Read more
OS X Yosemite 10.10 DP4 - Developer Prev...
Note: This is a Developer Preview. You must be a registered Apple Mac Developer to download this update. OS X Yosemite is Apple's newest operating system for Mac. An elegant design that feels... Read more
FinderPop 2.5.6 - Classic Mac utility, n...
FinderPop is a Universal preference pane that extends OS X's contextual menus using a FinderPop Items folder much as the Apple Menu Items folder used to do for the Apple menu. It has other features... Read more
SpiderOak 5.1.7 - Secure cloud backup, s...
SpiderOak is a multi-platform secure online backup, storage, access, and sharing solution engineered for the consumer and small businesses. You must first sign up to use SpiderOak. Running natively... Read more
Espionage 3.6 - Simple, state of the art...
Espionage offers state-of-the-art encryption and plausible deniability for your confidential data. Sometimes, encrypting your data isn't enough to protect it. That's why Espionage 3 goes beyond data... Read more
calibre 1.45.0 - Complete e-library mana...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital... Read more
iFFmpeg 4.3.1 - Convert multimedia files...
iFFmpeg is a graphical front-end for FFmpeg, a command-line tool used to convert multimedia files between formats. The command line instructions can be very hard to master/understand, so iFFmpeg does... Read more
Chromium 36.0.1985.125 - Fast and stable...
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web. FreeSMUG-Free OpenSource Mac User Group build is... Read more
pwSafe 3.0 - Secure password management...
pwSafe provides simple and secure password management across devices and computers. pwSafe uses iCloud to keep your password databases backed-up and synced between Macs and iOS devices. It is... Read more

Latest Forum Discussions

See All

MTN Review
MTN Review By Jessica Fisher on July 22nd, 2014 Our Rating: :: ADORABLE, SERENE, AND AMUSINGUniversal App - Designed for iPhone and iPad MTN is an adorable, talking pet mountain that is less game and more zen garden.   | Read more »
Fly High with Ninja UP! Now Available o...
Fly High with Ninja UP! Now Available on the App Store Posted by Jessica Fisher on July 22nd, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Bio Inc. Review
Bio Inc. Review By Nadia Oxford on July 22nd, 2014 Our Rating: :: SICKENING - IN A COMPELLING WAYUniversal App - Designed for iPhone and iPad Bio Inc is about orchestrating the medical destruction of a single person. If that doesn’... | Read more »
HELMUT Review
HELMUT Review By Andrew Fisher on July 21st, 2014 Our Rating: :: TRUNDLE SIMULATOR 2014Universal App - Designed for iPhone and iPad HELMUT is a fun, fleeting time-sink that offers a momentary distraction and nothing else.   | Read more »
Walkr Review
Walkr Review By Jennifer Allen on July 21st, 2014 Our Rating: :: ORIGINAL WALKINGiPhone App - Designed for the iPhone, compatible with the iPad Walking is a bit more exciting thanks to this planet building/discovering sim reliant... | Read more »
Zombie Commando Review
Zombie Commando Review By Jennifer Allen on July 21st, 2014 Our Rating: :: MINDLESS SLAUGHTERUniversal App - Designed for iPhone and iPad Briefly fun but ultimately forgettable, Zombie Commando will scratch an itch then be... | Read more »
Swords & Poker Adventures Review
Swords & Poker Adventures Review By Jennifer Allen on July 21st, 2014 Our Rating: :: SOULLESS POKER PLAYUniversal App - Designed for iPhone and iPad Swords & Poker Adventures is a mishmash of Poker and RPGing, but it lacks... | Read more »
Warhammer 40,000: The Horus Heresy: Drop...
Warhammer 40,000: The Horus Heresy: Drop Assault Coming Soon to iOS Posted by Jennifer Allen on July 21st, 2014 [ permalink ] Coming soon to iOS will be an all-new Warhammer 40,000 tactical strategy game by the name of The Horus Heresy: Drop As | Read more »
A Life Worth Dying For Review
A Life Worth Dying For Review By Jordan Minor on July 21st, 2014 Our Rating: :: A BEAUTIFUL MINDUniversal App - Designed for iPhone and iPad A Life Worth Dying For is a fascinating portrait of a serious subject.   | Read more »
Zombie Puzzle Panic Review
Zombie Puzzle Panic Review By Jordan Minor on July 21st, 2014 Our Rating: :: THE MATCHING DEADUniversal App - Designed for iPhone and iPad Zombie Puzzle Panic puts some pretty neat undead twists on Match-3 puzzling.   | Read more »

Price Scanner via MacPrices.net

Twelve South HiRise For MacBook – Height-Adju...
If you use your MacBook as a workhorse desktop substitute, as many of us do, a laptop stand combined with an external keyboard and pointing device are pretty much obligatory if you want to avoid... Read more
Why The Mac Was Not Included In The Apple/IBM...
TUAW’s Yoni Heisler cites Fredrick Paul of Network World whoi blogged last week that the Mac’s conspicuous absence from Apple and IBM’s landmark partnership agreement represents a huge squandered... Read more
Save $100 on 13-inch Retina MacBook Pros, plu...
Adorama has 13″ Retina MacBook Pros on sale for $100 off MSRP. Shipping is free, and Adorama charges sales tax in NY & NJ only: - 13″ 2.4GHz/128GB MacBook Pro with Retina Display: $1199 - 13″ 2.... Read more
Blurr it 2.3 for iOS – Quickly Blurs Selected...
Hyderabad, India based TouchLabs has announced a new update of Blurr it 2.3, their photography app for iOS users. Blurr it allows you to blur part of the image to hide potentially sensitive or... Read more
MacBook Airs on sale for $100 off MSRP, start...
Best Buy has the new 2014 MacBook Airs on sale for up to $100 off MSRP on their online store. Choose free home shipping or free local store pickup (if available). Prices valid for online orders only... Read more
Amazon Announces Kindle Unlimited: Unlimited...
Amazon.com has introduced Kindle Unlimited — a new subscription service which allows customers to freely read as much as they want from over 600,000 Kindle books, and listen as much as they want to... Read more
New Linksys Wireless Range Extenders Boost Wi...
Linksys has announced its new lineup of Linksys Wi-Fi Range Extenders. Consumers often experience a weak wireless signal in some parts of their house or apartment caused by blocking elements such as... Read more
MacBook Airs available starting at $719
The Apple Store has Apple Certified Refurbished 2013 & 2012 MacBook Airs in stock today starting at $719. An Apple one-year warranty is included with each MacBook, and shipping is free: 2013... Read more
Get the best deals on iPad minis with Apple r...
The Apple Store has Certified Refurbished 2nd generation iPad minis with Retina Displays available for up to $130 off the cost of new models, starting at $339. Apple’s one-year warranty is included... Read more
Best Buy’s College Student Deals: $100 off Ma...
Take an additional $100 off all MacBooks and iMacs, $50 off iPad Airs and iPad minis, at Best Buy Online with their College Students Deals Savings, valid through July 25th. Anyone with a valid .EDU... Read more

Jobs Board

*Apple* Computer Technician - Fairfield Coun...
Company DescriptionWe are an Apple Authorized Sales and Service Provider. We have been selling and servicing Apple computers in the Fairfield County area for over 20 Read more
*Apple* Computer Technician - Fairfield Coun...
Company DescriptionWe are an Apple Authorized Sales and Service Provider. We have been selling and servicing Apple computers in the Fairfield County area for over 20 Read more
Mac Expert - *Apple* Online Store Mexico -...
…MUST be fluent in English and Spanish to be considered for this position At Apple , we believe that hard work, a fun environment, creativity and innovation fuel the Read more
*Apple* Computer Technician - Fairfield Coun...
Company DescriptionWe are an Apple Authorized Sales and Service Provider. We have been selling and servicing Apple computers in the Fairfield County area for over 20 Read more
Mac Expert - *Apple* Online Store - Apple (...
**Job Summary** At Apple , we believe that hard work, a fun environment, creativity and innovation fuel the ultimate customer experience. We believe each customer Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.