Skip to content

Getting Yosemite AppleScript Progress Information

Yosemite (Mac OS X 10.10) introduced 4 new properties scripts can set to report progress information:

progress total steps (an integer)
progress completed steps (an integer)
progress description (text)
progress additional description (text)

See the Yosemite AppleScript Release Notes for full details.

What is not explained is how a host application can access this information and display a script’s progress in its own UI. Here’s how you do it.

At intervals the script will call the OSAActiveProc. Within this callback function you can make OSA calls that access the running script’s state. You start by getting a reference to the ‘AppleScript’ object. From there you can read the value of the four progress properties. The following code uses my own OSAID wrapper object (RKOSAID – don’t ask, Script Debugger is 20 year old code). You can use whichever OSA API you are most familiar with.

--  Provisional property ID constants until Apple puts them into a public API

#define pASProgressTotalSteps_LNS       'ppgt'
#define pASProgressStepsCompleted_LNS   'ppgc'
#define pASProgressDescription_LNS      'ppgd'
#define pASProgressAdditionalDescription_LNS 'ppga'

@interface RKOSAID (AppleScriptProgress)

- (NSDictionary*) appleScriptProgress;

@end

@implementation RKOSAID (AppleScriptProgress)

- (NSDictionary*) appleScriptProgress {

    // Get a reference to the 'AppleScript' object
    RKOSAID* as = [self propertyForPropertyID:pASTopLevelScript];

    // Extract the progress properties
    RKOSAID* totalSteps = [as propertyForPropertyID:pASProgressTotalSteps_LNS];
    RKOSAID* steps = [as propertyForPropertyID:pASProgressStepsCompleted_LNS];
    RKOSAID* description = [as propertyForPropertyID:pASProgressDescription_LNS];
    RKOSAID* addnlDescription = [as propertyForPropertyID:pASProgressAdditionalDescription_LNS];

    // Convert into Cocoa objects and return
    return @{@"totalSteps": @(totalSteps.descriptor.int32Value),
             @"steps": @(steps.descriptor.int32Value),
             @"description" : description.descriptor.stringValue,
             @"additionalDescription" : addnlDescription.descriptor.stringValue};
}

@end

NOTE: My -[RKOSAID propertyForPropertyID:] call wraps the OSAGetProperty() call defined in ASDebugging.h.

SEE ALSO: OSAID Leaks Cause Crashes.