Cocoa Scripting: Returning "null" vs. "missing value"

679 views Asked by At

It appears that AppleScript knows the special value null.

How do I return such a value from my Cocoa Scripting based app for a scriptable property?

If I return nil (NULL) or NSNull for a scriptable property getter from my Cocoa Scripting-based app, the script editor interprets that as missing value.

And if I return [NSAppleEventDescriptor nullDescriptor], AppleScript even shows an error.

2

There are 2 answers

2
pkamb On

I'm using the cMissingValue version of "null", like so:

NSAppleEventDescriptor(typeCode: UInt32(cMissingValue))

I decided to use that based on the testing below.

I'm using Swift to run and passing parameters to an AppleScript subroutine, using the code here:

Passing variables to an AppleScript

let parameters = NSAppleEventDescriptor.list()

let null         = NSAppleEventDescriptor.null()
let missingValue = NSAppleEventDescriptor(typeCode: UInt32(cMissingValue))

parameters.insert(null, at: 0)
parameters.insert(missingValue, at: 0)
return parameters

These parameters are passed to the AppleScript subroutine, and I've commented each results:

on nilTest(paramNull, paramMissingValue)
    display dialog paramNull buttons {"OK"} # execution error: Can’t make current application into type string. (-1700)
    display dialog paramMissingValue buttons {"OK"} #"msng"

    display dialog "" & paramNull buttons {"OK"} #"current application"
    display dialog "" & paramMissingValue buttons {"OK"} #"missing value"
end nilTest

The NSAppleEventDescriptor.null() version seems to for some reason be getting the "current application" value.

It seems like I may want to use the cMissingValue as shown in the other answer.

The variables can be nil-checked in AppleScript like so:

if yourVar is missing value then
    display dialog "is missing value" buttons {"OK"}
end if

NSAppleEventDescriptor.null() does not hit this check. Type cMissingValue does.

I've added it as a Swift Extension: NSAppleEventDescriptor.missingValue()

extension NSAppleEventDescriptor {

    static func missingValue() -> NSAppleEventDescriptor {
        return NSAppleEventDescriptor(typeCode: UInt32(cMissingValue))
    }

}
8
foo On

AppleScript uses a typeNull descriptor to indicate unassigned/no value, whereas missing value is represented by a typeType descriptor of cMissingValue. (It's analogous to the undefined vs null mess in JavaScript, and a similar PITA.)