TweetFollow Us on Twitter

Rapid Prototyping

Volume Number: 14 (1998)
Issue Number: 2
Column Tag: Programming Techniques

Rapid Prototyping

by John Schettino

An Object Oriented Approach to Using FaceSpan and AppleScript to Prototype Applications

Software Development 101

Just the other day I read a posting to a Macintosh programmers news group that asked a simple but powerful question. What design methodologies do most Macintosh programmers use? As I stared at the phosphors of my monitor, I recalled my years of formal study in Software Engineering. I learned all the state of the art (in the late 80s) software design methods when I was getting my Masters degree -- but what do I actually use in practice?

The answer is a bit surprising. It turns out that I usually use a technique called either incremental development or rapid prototyping. This approach relies on my own expertise in ad-hoc design and the fact that I'm usually working alone on a project. It doesn't hold up quite so well for large programmer teams. The basic idea is to quickly implement a subset of the application, use it -- or better yet let the customer use it, see what works and what doesn't, and then repeat the cycle. Each time through the cycle refine:

  • the requirements (what the application is supposed to do)
  • the interface (how the application looks)
  • the behavior (what the application does), and
  • the design (how the application is structured)

For this approach to succeed, using tools that support very fast implementation of successive versions of the prototype is critical. Discarding the prototype once it has served its purpose is also critical. This prevents overattachment to the initial version's implementation. It also keeps me from over-polishing the prototype! For these reasons I've selected AppleScript and FaceSpan as my Rapid Prototyping Environment.

The Tools

AppleScript is the Macintosh's bundled scripting language. It is a reasonable programming language for prototyping, since it includes basic block-programming constructs, subroutines, and several data types. It supports classes with data and member functions, and fairly complex data structures. There is also a wide array of scripting additions on the Internet that I use to round out the language. AppleScript is close enough to Java, C, or C++ to allow me to re-implement the prototype in any of those languages. It also reads a bit like psudocode so it can be used as a specification language for the final implementation. The big plus for AppleScript is that it can call on third-parties to perform complex tasks. That means databases, emailers, text editors, and even the Finder can be called on to perform major portions of a prototyped application. The big minus with AppleScript is that it completely lacks any capabilities for interface creation.

FaceSpan is a product from Digital Technology International that works as an interface tool with AppleScript or other OSA scripting languages, such as Frontier. Using FaceSpan I can create interfaces for AppleScript prototypes. The interface consists of several different styles of windows containing standard Macintosh interface elements. I then attach scripts to the windows and elements to process the events they generate. All the windows and scripts are contained in a single project file. I run the project within the FaceSpan environment while I'm developing it. Once it is working correctly, I save the project as a standard Macintosh executable file. In many ways it's simpler than it sounds.

The combination of AppleScript and FaceSpan is similar to HyperCard with several key advantages. Most important is the elimination of the Card/Background/Stack metaphor. In FaceSpan each window and it's window items behave as a unit, with their own message hierarchy. This yields "Mac-like" prototypes instead of "HyperCard-like" prototypes. FaceSpan also fully supports color, QuickTime, Drag and Drop, and other key Mac technologies. It has a rich set of interface elements to choose from. I've done pretty fancy interfaces with FaceSpan, creating and destroying window items on the fly, implementing direct manipulation interfaces, and so on. Some of the more interesting effects require a bit of script code, but at least that code is easily reused in other projects.

The Method

I like methods. A method is a little less formal than a procedure. It is a general description of the steps needed to get something done. If there is something in this method that doesn't work for you, then just work around it. The primary reason I develop a prototype is to refine my understanding of the application I'm creating. I also use it to get end-user feedback early in the design and implementation process while it is easy to make changes. The method I use to meet these goals with FaceSpan and AppleScript is quite simple:

  • First, create the static portions of the interface.
  • Second, add enough AppleScript to animate the interface at the most basic level.
  • Finally, add more AppleScript to implement as much of the application behavior as is needed for the prototype.

This three-step approach is not specific to FaceSpan and AppleScript. It's the same method I use in any language. When using these tools it is just a lot faster to complete each step. Depending on the goal of the prototype it is usually possible to stop before completing all three steps. For example, a UI designer might simply want to draw a possible interface and add a bit of AppleScript to animate it. The prototype could then be handed over to users and its usability could be assessed.

Drawing Interfaces in FaceSpan

Begin with whatever you know about the desired application's look and behavior and start creating windows in FaceSpan. This is a good time to review the Macintosh Human Interface Guidelines, also known as the human-computer interface (HCI) guidelines. I'm a big fan of following these, because applications that follow the guidelines are easier for users to learn and use. The FaceSpan Window Editor is a great environment to experiment with different layouts, but even more so, it's a place where the developer can see first hand the effects of following (or ignoring) the HCI guidelines. Here's a simple example. There are detailed rules for laying out the elements of a modal dialog box. The first dialog box below follows these rules to the letter, the second does not.


Figure 1. Conforming and Non-conforming dialog boxes.

Although the two contain the same buttons, the first conforms to the HCI guidelines. The default push button is in the right location, there is a correct amount of white space between the window items and the window border, and the icon is placed correctly. The result is a dialog box that is instantly recognizable to a Mac user. FaceSpan encourages this type of consistency throughout the application, but it by no means enforces it.

FaceSpan's Window Editor creates three different types of windows. Document windows are used for main windows. They can be resizable, closeable, and zoomable. Their optional titles are distinct from their name, as used in scripts. Modal windows can be titled or untitled and, unlike Document windows, must be closed before any other windows can receive events. The last window type is floating Windoid. These are windows that float on top of all Document windows. They are usually used for tool palettes.

A window contains zero or more window items. The upper limit of window items is 330. There are 14 different types of window items, and these types are further customizable using Forms. For example, the Button window item can have either a standard or a 3-D visual representation.

The Window Editor consists of a pair of tool palettes. The window under construction is displayed almost exactly as it will appear. New window items can be dragged onto the window, or drawn on the window. Window items have several properties that control their behavior. For example the visible and enabled properties determine if a particular window item is visible, and usable. If its enable property is false, it displays in a grayed-out style.

Figure 2. The FaceSpan Window Editor.

Figure 2 shows a complex preferences Modal window in FaceSpan's window editor. This window uses several window items, including labels, textboxes, boxes, checkboxes, and buttons (called push buttons by FaceSpan.)

In addition to the window editor, an application has full control over the menu bar. Basic menu capabilities are supported, as well as limited (single level) hierarchical menus. The menu bar support is the weakest portion of FaceSpan. Applications can have only a single menu item in the Apple menu and have no access to the Help menu.

Animating the Interface

There are three basic forms of interface behavior: workflow control, feedback, and application specific behavior. The next step in prototyping is to implement the first two forms. By workflow control I mean the degree to which the application controls what the user can do at any given point in time. This includes simple things like push button and menu sensitivity, as well as window interactions. It also includes managing dependant window items. Feedback is the use of visual and auditory messages in the application. For example, feedback is displaying a confirmation dialog box when the user closes a window, or playing a beep when invalid data is entered into a text box.

The first step is to get the ball rolling at application startup. Let's assume I have a prototype that needs to open three windows when it is launched. I make a project in the FaceSpan environment, draw three windows in the Window Editor, and then save the project as an executable. When the user double clicks the appliction icon in the Finder, it launches just fine, but no windows are displayed. I need to add some AppleScript to the project to link the launching event to several actions. When the user launches a FaceSpan application a run event message is sent to the project script. If the user drops a file on the application icon, an open event message and a list of file references is sent to the project script instead. I want to open three windows when the user launches the application, so I add an on run handler in the project script:

on run
  -- get prefs
  set {p1, p2, p3} to storage item "positions"
  open window "Call Manager" 
    with properties {bounds:p1}
  open window "Status" -
    with properties {position:p2, zoomed:false}
  open window "Call Manager - driver" 
    with properties {position:p3, zoomed:false}
end run

Most Macintosh applications keep track of window positions for the user. I can do that for my prototype as well. This handler uses a storage item to keep track of user placement of the windows. Storage items are named containers where an application can store and recall any type of data. The actual data is kept in the resource fork of the application. Recall that this is the executable version of the project file.

When the user double clicks the application icon, the on run handler of the project script is called. I begin by recalling three positions (positions are a FaceSpan datatype that specifies the x, y, width, and height of a window) from storage. I use each position to place and size each window exactly where the user left them when they last quit the prototype. I open each window use the open window command. A Window is controlled by the settings of its properties, and I can set the values of window properties in the open window command using the with properties modifier. I use this to set the initial position of each window to the stored value. I need to create the initial values for the three positions and save them in the "positions" storage item within the FaceSpan environment. I also need to somehow capture the current location and size of each window and update the storage item when the user quits the prototype.

Once a window is open the user can interact with it. They can click buttons, enter text into textboxes, check checkboxes and radio buttons, and so on. If there are no scripts attached to a window then these actions don't do anything specific to the prototype. The window behaves like a fill-in-the-blanks form. All the window items and the window itself will work, but unless the prototype does something with the information or actions the user takes, not much else will. FaceSpan does a lot of the hard work: the user can enter text into text fields, select radio buttons or checkmarks, tab between fields, scroll scrollable textboxes, and what not. What is missing is the application-specific actions that link the whole interface together.

For example, the modal dialog window in Figure 2 has a checkbox (displayed as a pull-down flag) labeled "Advanced Options." When the user toggles this checkbox "on" the window should expand to show the window items below it, and the OK push button should move down to the bottom. Clicking it again should collapse the window back to its original size and move the OK push button back to the original location. When I draw the dialog window in the FaceSpan Window Editor I set the OK push button growth property to move both. That tells FaceSpan to move it in both directions whenever the window size changes. In effect it becomes attached to the lower right corner of the window. What I want to do is resize the window between two fixed sizes, based on the setting of the "Advanced Options" checkbox. I add a handler to the script attached to the checkbox that resizes the window when the user changes the checkbox's value. That handler is very simple:

on hilited theObj
  if hilite then
    set height of my window to 555
  else
    set height of my window to 345
  end if
end hilited

When the user clicks to push a button, checkbox, or radio button window item the hilited event is sent to its attached script. The hilite property of the checkbox is true if it is checked and false otherwise. This little script changes the window size to one of two sizes, based on the hilite property value, each time the checkbox is clicked.

Figure 3.

I create lot of the animation of a prototype interface using similar techniques. Handlers for push button clicks (on hilited) or listbox selections (on selection made) usually enable or disable other window items, open or close other windows, or enable or disable menu items.

When the interface is fully animated the prototype is sufficient to answer a lot of questions about the final product. Does the interface work well? Is it easy to figure out how to accomplish a given task? Is feedback clear and consistent? The final step for a prototype is to add some or most of the application specific behavior. This is both a valuable and a dangerous step. Valuable because of what it can reveal about a potential design, and dangerous because if the prototype becomes "too functional" there is a real danger to ship it. By using FaceSpan and AppleScript, you are relieved of that danger, while still retaining the benefit of trying out a design before committing many hours to a C++ implementation. In other words, you're pretty much assured of having to throw away the prototype!

Adding Application-Specific Behavior

Adding application behavior is pretty much an exercise in AppleScript programming. The FaceSpan message hierarchy provides a lot of flexibility in the placement of handlers for FaceSpan event messages as well as application specific handlers. My job is to convert the various FaceSpan event messages into application-specific messages. FaceSpan event messages signal interface events (hilited, selection made, and so forth) while application-specific messages signal much higher-level events (produce a report, export to file, open database, and so on.) I then write handlers for those application-specific messages in AppleScript. This approach lets me reuse more of the design from the prototype because I'm able to separate the application-specific portions of each handler from the interface-specific portions. If I go on to implement the final application in C++ or Java, the interface code will be quite different than FaceSpan. The actual application specific behavior will also be coded differently, but the AppleScript code I write in the prototype can act as pseudocode.

A simple example is a push button in a window. When the user clicks the push button FaceSpan sends a hilited event message to its attached script, and then on to the window the button is in, and finally to the project script. The message flows along the message hierarchy until it is handled by a script, so I can place the on hilited handler wherever it makes the most sense. My rule is to place the handler in the script attached to the window or window item closest to the item generating the event message, unless a very similar action is performed regardless of which window item is generating it. For push buttons, I generally put the on hilited handler in the script attached to the push button. This handler converts the FaceSpan event message (hilited) into an application-specific function call. Function calls in AppleScript send a user-defined command message corresponding to the function name into the message hierarchy. Here's an example script that converts a FaceSpan event message to an application-specific user-defined command:

on hilited theObj set address to contents of textbox "digits" - as string sendCall(address) set contents of textbox "digits" to "" end hilited

The handler is from a prototype Call Management application. In this prototype the main window consists of a graphical representation of a call, a textbox named "digits", and a push button labeled "Send". When the user clicks Send, I want to extract the current phone number from the textbox and place a telephone call to that number. I then want to clear the textbox. There are two different things happening here. Getting the phone number and clearing the textbox are both interface-specific actions, so I take care of them in this handler. The second action is placing a call to the entered number. That has nothing to do with the interface, and I'd like to separate the code out so I can at least have the option of reusing the design. I do this by calling a user-defined function. This in effect converts the FaceSpan hilited event message into an application-specific event message named sendCall(). Now all I have to do is implement the AppleScript handler for sendCall(). This handler is totally separate from the FaceSpan interface, and can be placed in a script anywhere along the message hierarchy (window item, window, and project). Where this is placed depends on several factors, including the ultimate target implementation language. For this prototype, I placed the handler in the project script:

on sendCall(phoneNum)
  if isConnected then
    tell window "Status"
      setMsg("Dial " & phoneNum)
      enableWaiting()
    end tell
    tcp write data "Dial " & phoneNum & LF -
      stream tcpDialogSocket
  end if
end sendCall

In the handler I send a protocol message through a TCP/IP socket to a host application. I also enable what amounts to a thread in another window (again using an application-specific message named enableWaiting()) that uses the FaceSpan idle handler to poll a TCP/IP socket for a reply. I'm taking advantage of the excellent shareware TCP/IP Scripting Addition by Mango Tree Software to perform the TCP/IP operations.

Don't get too hung up on the actual code, what's more important is to understand what it shows. When I implement the actual application it's pretty clear that the code must write a string to a TCP/IP socket to make a call, and once it's done this it must wait for a response. This design applies just as well to the final application as it does to this prototype.

Object Oriented Programming

I generally take an object-oriented approach to application design. FaceSpan and AppleScript fully support object-oriented implementations. For those not interested in or concerned with objects, a purely functional approach can also be used. If objects are important to the prototype, then there are several options available when using the FaceSpan/AppleScript combination. FaceSpan's windows and window items are themselves objects, while AppleScript includes its own script objects.

Objects in FaceSpan

In FaceSpan, every window is considered a window template. This means that FaceSpan considers every window, including all its window items and attached scripts, to be a class of sorts. An application can either use the template directly, or it can create several instances of the template. Each instance contains a complete copy of the window, including window properties and attached script properties. Each window instance is assigned a unique window id property. The open window command opens a window based on the template created in the Window Editor.

Window items also are objects. They contain properties as well as data, and can be created and destroyed dynamically. When a window is created in the Window Editor, the initial set of window items is specified and their property values are set. The application has complete control over these values, and can even override them when the window template is opened. The following code fragment dynamically creates several window items in a window.

on displayCall(calledNumber, calledNumberId, -
    isActive, isRadio, isInConf, -
    isConf, lineFrom, nodeX, nodeY)
  local xPos, ypos, iconArt, lineProps
  set ypos to (nodeY * 60) - top
  set xPos to nodeX * 80
  
  if isRadio then
    set radioItem to id of (make radio button -
      with properties {position:{4, ypos},width:16,-
      height:16, script:none, hilite:isActive, -
      cnum:calledNumber, cid:calledNumberId} -
      at end of window id theWindow)
    set index of window item id radioItem to 2
  end if
  
  set theIndex to -
    (index of graphic line "divLine") + 1
  if isConf then
    set iconArt to {class:resource info, -
      type:"cicn", name:"group", id:5001}
  else
    set iconArt to {class:resource info, -
      type:"ICON", name:"Big Off Tone", id:5002}
  end if
  
  set iconItem to id of (make icon with properties-
    {artwork:iconArt, position:{4 + xPos, -
    ypos - 10}, width:36, height:36, -
    draggable:true, droppable:true, script:none,-
    selection rule:as push button, -
    balloon:"ISP Id is: " & calledNumberId, -
    cnum:calledNumber, cid:calledNumberId, -
    conf:isInConf} at end of window id theWindow)
  set index of window item id iconItem to theIndex
  
  if (lineFrom = -1) then 
    set lineProps to {position:{18, ypos + 8}, -
      width:80, height:1, script:none}
  else if (lineFrom = 0) then 
    set lineProps to {position:{(80 * (nodeX - 1)) -
      + 22, ypos - 60}, width:1, height:68, -
      script:none}
  else
    set lineProps to {position:{(80 * lineFrom) + -
      14, ypos + 8}, width:80 * (nodeX - lineFrom),-
      height:1, script:none}
  end if
  
  set lineItem to id of (make graphic line -
    with properties lineProps -
    at end of window id theWindow)
  set index of window item id lineItem to theIndex
  
  if (lineFrom = 0) then
    set lineItem to id of (make graphic line -
      with properties {position:{(80 * (nodeX - 1))-
      + 22, ypos + 8}, width:72, height:1,-
      script:none} at end of window id theWindow)
    set index of window item id lineItem to theIndex
  end if
  
  set labelItem to id of (make label -
    with properties {position:{xPos + 10, ypos + -
    24}, width:80, height:16,contents:calledNumber,-
    script:none} at end of window id theWindow)
  set index of window item id labelItem to theIndex
  
end displayCall

This is a meaty handler that creates several window items. It shows several interesting things. First, the algorithm used to place the radio button, icon, label, and lines is reusable. I used virtually the same algorithm in a Java and a NewtonScript version of the final application. Second, the application has total control over the placement and property values for window items it creates. Third, I'm adding application-specific properties to the radio button and icon window items. I use these window items to hold information I need (caller number and conference information) to associate with the call, but don't want to store separately. Finally, notice that each window item has its script property set to none. This is one case where I take advantage of the FaceSpan message hierarchy for performance reasons. Whenever one of these window items generates an event message I can handle it in the window's attached script with a general handler. Here's the hilited event handler:

on hilited theObj
  try
    if class of theObj is radio button then
      set theCallId to cid of theObj
      switchCall(theCallId)
    end if
  on error
  end try
end hilited

I dynamically create radio buttons, icons, graphic lines, and labels as children of the window. Of these, only radio buttons and icons generate the hilited event message. In this prototype I don't want to perform any actions if the user clicks one of the dynamic icons, and there are no other radio buttons in the window except those I create dynamically. When I add the on hilited hander to the script attached to the window, it is called whenever the user clicks something (radio button, checkbox, push button, or icon) in the window, but only if that window item does not include its own on hilited hander in its attached script. In this case I need to verify only that the class of the sender of the message is radio button. If it is, then it must be one of my dynamically created ones.

I use the class of operator to determine if the object generating the message is a radio button. If it is, then I convert the FaceSpan event message into an application specific message named switchCall(). I retrieve the application specific property cid from the radio button, since that's the id that the server process knows about. This is an example of treating window items like objects, since each item contains its own unique data.

Objects in AppleScript

AppleScript also has its own little-used object/class system. Each script in AppleScript is considered a Script object that contains methods (called handlers) and data (called properties.) The script/end script command defines a script object within a script. The basic form is:

script className
  property parent: otherClassName

  property p1: value1

  on handlerName(params)
  end
end script

A script object can have zero or one parent script property, zero or more other properties, and zero or more handlers. This is more like Java than C++ since there is only single inheritance. There is also no private or protected data or methods. Everything is public. For prototyping, this is not a major hardship. Script objects are a little different than classes in most object-oriented languages in that the script/end script commands actually make a single instance. In the above example the commands make a single instance of the class named className. To make several instances of the class I'd have use the copy command to copy className. Instead of doing this, I can place the script/end script commands in a handler. Then the handler acts like a constructor. Every time I call the constructor a new instance of the class is created. Parameters to the hander can be used in the property statements of the script to provide initial values to newly created objects. This is an example of a simple constructor handler:

on makeMyObj(name)
  script myObj
    property myName: name
    on getName()
      return myName
    end getName
  end script

  return myObj
end

Calling makeMyObj("Fred") returns an instance of the myObj script object with its myName property initialized to "Fred".

Combining script objects with FaceSpan allows for encapsulating all of the handlers and data associated with a group of dynamic window items into one object. I use this technique to bind all the methods and data for a meeting in a meeting object in an example in by book, AppleScript Applications: Building Applications in FaceSpan and AppleScript, in the DateMinder application. This application implements a PIM that includes a Day view. The Day view is a window that displays a cluster of three window items for each meeting in a day. Here is a portion of the constructor and script object for a meeting:

on makeDayItem(itemclass, itemDetails, itemNote)
  local pos, startAt, meetingLength
  
  if itemclass = "Meeting" then
    set {pos, startAt, meetingLength} to itemDetails
    updateCalendarMeetMarks(startAt, true)
  else
    set startAt to 0
    set meetingLength to 0
    set pos to itemDetails
    updateCalendarOtherMarks(itemclass, true)
  end if
  
  script DayObject
    property theIndex : 0
    property barIndex : 0
    property iconIndex : 0
    property textIndex : 0
    property myPos : pos
    property myTime : startAt * 15 * minutes
    property myLength : meetingLength
    property myClass : itemclass
    property myNotes : itemNote
    

    on getItemInfo()
      if itemclass = "Meeting" then
        return {itemclass:myClass, xPos:myPos,-
          starttime:myTime, duration:myLength, -
          notes:myNotes}
      else
        return {itemclass:myClass, xPos:myPos, -
            notes:myNotes}
      end if
    end getItemInfo
    
    on resizeMeeting(theObj)
    end resizeMeeting

    on createImage()
    end createImage

    on updateMeeting(newTime, newDuration, newText)
    end updateMeeting

    on move (theInfo)
    end move

    on redraw()
    end redraw

    on openWindow()
    end openWindow

    on closeWindow()
    end closeWindow

    on windowName()
    end windowName

    on updateWindow()
    end updateWindow

    on adoptDetailWindow(oldWindowName)
    end adoptDetailWindow

    on updateItemText(newNote)
    end updateItemText

    on updateItemTextAndDisplay(newNote)
    end updateItemTextAndDisplay

    on remove()
    end remove
    
  end script
  
  return DayObject
  
end makeDayItem

I call the makeDayItem() handler to create a day item object. Once it is created I draw it's graphical representation in the Day window by calling the createImage() handler. An example of this is in the handler called when the user drags an icon onto the window to create a new meeting:

on newDayItem(theClass, theInfo)
  local theDayItem
  set theDayItem to -
    makeDayItem(theClass, theInfo, "")
  set end of theDayItems to theDayItem
  tell theDayItem to createImage()
end newDayItem

In this handler I create a new day item object by calling the day item constructor handler, and save the object in a list of all day items stored in a property. I then call the createImage() handler in the object to draw the object in the window. Any script needing to access data associated with the object, or to change its contents or location, need call only handlers in the object. I don't have to know how it is implemented, what window items are associated with it, or how to modify their properties. As I said, it's a powerful combination.

Moving From Prototype to Product

Once the prototype is completed and ready to retire, I don't just ignore it. Rather it can be mined for valuable information. The interface will have to be reimplemented in the target language (using PowerPlant, or the Constructor for Java, or by hand coding, depending on the implementation language). The prototype serves two roles here: it acts as a guide when laying out the interface and as a specification for naming the elements of the interface.

The same holds true for the AppleScript scripts. They act as a high-level specification language for the final code. Algorithms implemented in AppleScript are highly reusable, as are data structures and class hierarchies. I'm not suggesting that it's just a matter of "porting over" to C++ or Java, but at least I've already got a working solution to use when I'm doing the final implementation.

One Example of a Prototype That Worked

This is not just some abstract article - I've used these techniques many times when creating prototypes for GTE Laboratories. Here at the labs fast turn around times are critical when we're mocking up applications. By using this method and these tools, I've created many successful demos using AppleScript and FaceSpan. When we recreate a particular application in a production system, we first capture the design by dissecting the prototype.

One such example is a Call Management client application for an Internet telephony project. This application drives a server front end to allow the user to create and manage many telephone calls. Calls can be placed, merged into conferences, and dropped. Furthermore the user can have many calls active at the same time. The ultimate implementation target for the client application was Java, but much of the protocol used to communicate between the client and server was undefined and we needed a usable prototype in just two weeks. Using the method outlined in this article, and the TCP/IP osax from Mango Tree Software, I was able to create a professional prototype with a direct manipulation interface. This prototype carried us through the demo, and then was used for the final Java application over the next two months. The running application is shown below.

Figure 4.

As you can see, the application looks and behaves like any other Macintosh application. The icons on the scrolling display support drag & drop -- just drag a phone icon on top of another to merge the calls into a conference, or drag a phone icon out of a conference and onto the main window to split that call out of the conference.

Building this prototype in FaceSpan and AppleScript let me focus on the important details including creating a layout algorithm for the call graph, finalizing and debugging the TCP/IP protocol between client and server, and creating an enjoyable and usable interface for call manipulation. I didn't need (or have time) to struggle with the details of coding the application in C++ or Java. Even so, I was still able leverage the time spent on the prototype when building the final version in Java. I also re-implemented it in a custom NewtonScript application. Even there the time spent on the prototype reaped large rewards when designing the GUI in the Newton Toolkit and implementing the application in NewtonScript.

Prototyping Can Work For You

There are at least three good reasons to create a prototype before building an application. A prototype can help answer tough questions about an interface: how usable is it, does it work better one way or another, what is the optimal placement of controls in a window. A prototype is usually ready to use in short order and can fill in for the final application while it is being written. A prototype also lets you play "what if" games with different algorithms and data structures. As long as you're willing to throw it away, it's almost always worth the investment in time.

FaceSpan and AppleScript provide a powerful and rich environment for rapid prototyping. FaceSpan interfaces can be designed such that they are full Macintosh interfaces. The tool provides a fast way to mock up interfaces, and those interfaces can be quickly modified as the prototype evolves. In a similar manner AppleScript is a wonderful prototyping language. The syntax is like psuedocode, so the resulting scripts act as documentation when moving to C++ or Java. It supports object-oriented programming, as well as a huge library of osax building blocks and access to scriptable applications. These tools and this method are valuable additions to any programmer's toolbox.

References


John Schettino is an author and Senior Member of the Technical Staff at GTE Laboratories, Inc. He is the co-author of the books BASIC for the Newton: Programming for the Newton with NS BASIC and AppleScript Applications: Building Applications with FaceSpan and AppleScript, both published by AP Professional. He is also a contributing editor for the Handheld Systems Journal and for the web eZine Mobilis, where he writes about Newton and WindowsCE. You can reach him via http://members.aol.com/pdcjohns.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Summon your guild and prepare for war in...
Netmarble is making some pretty big moves with their latest update for Seven Knights Idle Adventure, with a bunch of interesting additions. Two new heroes enter the battle, there are events and bosses abound, and perhaps most interesting, a huge... | Read more »
Make the passage of time your plaything...
While some of us are still waiting for a chance to get our hands on Ash Prime - yes, don’t remind me I could currently buy him this month I’m barely hanging on - Digital Extremes has announced its next anticipated Prime Form for Warframe. Starting... | Read more »
If you can find it and fit through the d...
The holy trinity of amazing company names have come together, to release their equally amazing and adorable mobile game, Hamster Inn. Published by HyperBeard Games, and co-developed by Mum Not Proud and Little Sasquatch Studios, it's time to... | Read more »
Amikin Survival opens for pre-orders on...
Join me on the wonderful trip down the inspiration rabbit hole; much as Palworld seemingly “borrowed” many aspects from the hit Pokemon franchise, it is time for the heavily armed animal survival to also spawn some illegitimate children as Helio... | Read more »
PUBG Mobile teams up with global phenome...
Since launching in 2019, SpyxFamily has exploded to damn near catastrophic popularity, so it was only a matter of time before a mobile game snapped up a collaboration. Enter PUBG Mobile. Until May 12th, players will be able to collect a host of... | Read more »
Embark into the frozen tundra of certain...
Chucklefish, developers of hit action-adventure sandbox game Starbound and owner of one of the cutest logos in gaming, has released their roguelike deck-builder Wildfrost. Created alongside developers Gaziter and Deadpan Games, Wildfrost will... | Read more »
MoreFun Studios has announced Season 4,...
Tension has escalated in the ever-volatile world of Arena Breakout, as your old pal Randall Fisher and bosses Fred and Perrero continue to lob insults and explosives at each other, bringing us to a new phase of warfare. Season 4, Into The Fog of... | Read more »
Top Mobile Game Discounts
Every day, we pick out a curated list of the best mobile discounts on the App Store and post them here. This list won't be comprehensive, but it every game on it is recommended. Feel free to check out the coverage we did on them in the links below... | Read more »
Marvel Future Fight celebrates nine year...
Announced alongside an advertising image I can only assume was aimed squarely at myself with the prominent Deadpool and Odin featured on it, Netmarble has revealed their celebrations for the 9th anniversary of Marvel Future Fight. The Countdown... | Read more »
HoYoFair 2024 prepares to showcase over...
To say Genshin Impact took the world by storm when it was released would be an understatement. However, I think the most surprising part of the launch was just how much further it went than gaming. There have been concerts, art shows, massive... | Read more »

Price Scanner via MacPrices.net

AT&T has the iPhone 14 on sale for only $...
AT&T has the 128GB Apple iPhone 14 available for only $5.99 per month for new and existing customers when you activate unlimited service and use AT&T’s 36 month installment plan. The fine... Read more
Amazon is offering a $100 discount on every M...
Amazon is offering a $100 instant discount on each configuration of Apple’s new 13″ M3 MacBook Air, in Midnight, this weekend. These are the lowest prices currently available for new 13″ M3 MacBook... Read more
You can save $300-$480 on a 14-inch M3 Pro/Ma...
Apple has 14″ M3 Pro and M3 Max MacBook Pros in stock today and available, Certified Refurbished, starting at $1699 and ranging up to $480 off MSRP. Each model features a new outer case, shipping is... Read more
24-inch M1 iMacs available at Apple starting...
Apple has clearance M1 iMacs available in their Certified Refurbished store starting at $1049 and ranging up to $300 off original MSRP. Each iMac is in like-new condition and comes with Apple’s... Read more
Walmart continues to offer $699 13-inch M1 Ma...
Walmart continues to offer new Apple 13″ M1 MacBook Airs (8GB RAM, 256GB SSD) online for $699, $300 off original MSRP, in Space Gray, Silver, and Gold colors. These are new MacBook for sale by... Read more
B&H has 13-inch M2 MacBook Airs with 16GB...
B&H Photo has 13″ MacBook Airs with M2 CPUs, 16GB of memory, and 256GB of storage in stock and on sale for $1099, $100 off Apple’s MSRP for this configuration. Free 1-2 day delivery is available... Read more
14-inch M3 MacBook Pro with 16GB of RAM avail...
Apple has the 14″ M3 MacBook Pro with 16GB of RAM and 1TB of storage, Certified Refurbished, available for $300 off MSRP. Each MacBook Pro features a new outer case, shipping is free, and an Apple 1-... Read more
Apple M2 Mac minis on sale for up to $150 off...
Amazon has Apple’s M2-powered Mac minis in stock and on sale for $100-$150 off MSRP, each including free delivery: – Mac mini M2/256GB SSD: $499, save $100 – Mac mini M2/512GB SSD: $699, save $100 –... Read more
Amazon is offering a $200 discount on 14-inch...
Amazon has 14-inch M3 MacBook Pros in stock and on sale for $200 off MSRP. Shipping is free. Note that Amazon’s stock tends to come and go: – 14″ M3 MacBook Pro (8GB RAM/512GB SSD): $1399.99, $200... Read more
Sunday Sale: 13-inch M3 MacBook Air for $999,...
Several Apple retailers have the new 13″ MacBook Air with an M3 CPU in stock and on sale today for only $999 in Midnight. These are the lowest prices currently available for new 13″ M3 MacBook Airs... Read more

Jobs Board

*Apple* Systems Administrator - JAMF - Syste...
Title: Apple Systems Administrator - JAMF ALTA is supporting a direct hire opportunity. This position is 100% Onsite for initial 3-6 months and then remote 1-2 Read more
Relationship Banker - *Apple* Valley Financ...
Relationship Banker - Apple Valley Financial Center APPLE VALLEY, Minnesota **Job Description:** At Bank of America, we are guided by a common purpose to help Read more
IN6728 Optometrist- *Apple* Valley, CA- Tar...
Date: Apr 9, 2024 Brand: Target Optical Location: Apple Valley, CA, US, 92308 **Requisition ID:** 824398 At Target Optical, we help people see and look great - and Read more
Medical Assistant - Orthopedics *Apple* Hil...
Medical Assistant - Orthopedics Apple Hill York Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Now Read more
*Apple* Systems Administrator - JAMF - Activ...
…**Public Trust/Other Required:** None **Job Family:** Systems Administration **Skills:** Apple Platforms,Computer Servers,Jamf Pro **Experience:** 3 + years of Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.