Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AppleScript: Getting a list of all properties of an object or class

Tags:

applescript

In order to store an object's values for external (outside AS) access, I need to be able to get every property of that object, and then I'd try to coerce it to text and store it somehwere.

How do I get the list of properties that an object holds. As an example, I can write this:

tell me
  get properties
end tell

That works for a script object.

But for many other objects, I simply get an error such as "descripter type mismatch", like here:

tell application "iTunes"
  get properties of file track 1
end tell

Now, I know the excellent Script Debugger can do it (it can show any object's entire set of properties), so it should be possible in written AppleScript as well. What's the secret to this?

like image 708
Thomas Tempelmann Avatar asked Nov 21 '10 20:11

Thomas Tempelmann


3 Answers

There is a trick you can use, because you can force Applescript to tell you the error, and this text includes the properties of the object that was the target.

set myThing to {FirstName:"Fred", LastName:"Smith"}
ListProperties(myThing)
on ListProperties(MyObject)
try
    get properties of MyObject
on error errText number errNum
    set pStart to offset of "{" in errText
    set structure to text pStart thru ((length of errText) - 2) of errText
    set TIDL to AppleScript's text item delimiters
    set AppleScript's text item delimiters to ","
    set fields to text items of structure as list
    set myMessage to ""
    repeat with f from 1 to count of fields
        set AppleScript's text item delimiters to ":"
        set theseItems to text items of (item f of fields) as list
        set itemPropName to text 2 thru length of item 1 of theseItems
        set itemValue to item 2 of theseItems
        set myMessage to myMessage & "Property Label: " & itemPropName & tab & "Value: " & itemValue & linefeed
    end repeat
    set AppleScript's text item delimiters to TIDL
    display dialog myMessage
end try
end ListProperties
like image 140
Ian Avatar answered Nov 19 '22 03:11

Ian


Mark Alldritt, the author of Script Debugger, was so kind to explain the "secret" to me.

Script Debugger uses some special AppleScript API functions, including OSAGetPropertyNames(), to get to this information.

Hence, if I write a wrapper in, for instance, C, I can probably get to this, too.

Update

The Cocoa Scripting API has a dedicated classes for this (NSScriptSuiteRegistry and NSScriptClassDescription) - the framework builds this information from reading an app's scripting definition (.sdef) file. With that, all the available class and their properties can be learned quite easily.

like image 38
Thomas Tempelmann Avatar answered Nov 19 '22 03:11

Thomas Tempelmann


Script Debugger is Applescript, just with a bunch of programming tools placed around it. But a "descriptor type mismatch" really shouldn't enter into it. Can you show your code, because this works just fine in Script Editor:

tell application "Finder"
    set theFile to choose file
    get properties of theFile -- the "return" keyword also works here as well
end tell

Different applications will behave different, but without example code, there are too many variations to say definitively.

Update per comment and updated question: Again, different applications behave differently. An application actually has to have a properties property in order to get a record returned to you (though sometimes this is different from other information that can be gained from an object). Typically, this is implemented at a root class—item in most cases; iTunes doesn't allow for this. Not even Script Debugger can get around that.

like image 4
Philip Regan Avatar answered Nov 19 '22 02:11

Philip Regan