Search code examples
applescriptautomatorapplescript-objc

How can I convert the input __NSArrayM into an AppleScript list in an Automator Action project?


Automator Action

I am making a custom Automator action for manipulating text input. I tested the input to see what class it was and the result was __NSArrayM. This means that I need to somehow convert this input into a list that AppleScript can understand—and eventually to a string. I just need to isolate the string and then convert it back to the same object for the output.

Summary:

  • Convert the __NSArrayM input to an AppleScript list object
  • Convert AppleScript list object back to a __NSArrayM for the output

I would like my automator to look something like this: enter image description here

Coding Attempt in XCode

My attempt at coding this looks like:

script Change_Case
    property parent : class "AMBundleAction"
    property menuChoices : {"Title Case","UPPER CASE","lower case","tOGGLE cASE"}
    property menuSelection : 0
    on runWithInput_fromAction_error_(input, anAction, errorRef)
        set inputClass to class of input -- just for debugging

        set menuSel to menuSelection
        if menuSel is 0 -- Title Case
            display dialog menuSel as string
        end if

        tell class "NSArray" of current application to set inputValues to arrayWithObjects_(input)
        log inputValues -- just for debugging
    end runWithInput_fromAction_error_
end script

Final Code Update

I thought I would post the final code to my automator action for completeness. The key step was to make the input and output com.apple.cocoa.stringas shown in the picture below.

script Change_Case
    property parent : class "AMBundleAction"
    property menuChoices : {"Title Case","UPPER CASE","lower case","tOGGLE cASE"}
    property menuSelection : missing value
    property array : class "NSArray"
    
    on runWithInput_fromAction_error_(input, anAction, errorRef)
        set inputValues to input as list
        set theString to item 1 of inputValues

        if (menuSelection as string) is "missing value"
            set menuSelection to 0
        end if
        set menuSelection to menuSelection as integer
        
        if menuSelection is 0 -- Title Case
            --display dialog "Title Case, Menu Selection ID: " & menuSelection as string
            set mycode to "import sys; print sys.argv[1].title()"
            set myscript to "/usr/bin/python -c " & mycode's quoted form & " " & quoted form of theString
            set output to (do shell script myscript) as string
        end if
        if menuSelection is 1 -- UPPER CASE
            --display dialog "Upper Case, Menu Selection ID: " & menuSelection as string
            set mycode to "import sys; print sys.argv[1].upper()"
            set myscript to "/usr/bin/python -c " & mycode's quoted form & " " & quoted form of theString
            set output to (do shell script myscript) as string
        end if
        if menuSelection is 2 -- lower case
            --display dialog "Lower Case, Menu Selection ID: " & menuSelection as string
            set mycode to "import sys; print sys.argv[1].lower()"
            set myscript to "/usr/bin/python -c " & mycode's quoted form & " " & quoted form of theString
            set output to (do shell script myscript) as string
        end if
        if menuSelection is 3 -- tOGGLE cASE
            --display dialog "Swap Case, Menu Selection ID: " & menuSelection as string
            set mycode to "import sys; print sys.argv[1].swapcase()"
            set myscript to "/usr/bin/python -c " & mycode's quoted form & " " & quoted form of theString
            set output to (do shell script myscript) as string
        end if
        return output
    end runWithInput_fromAction_error_
end script

inputautomator


Solution

  • Is the goal of the script to take an array of text strings, and change their case based upon the menuSelection?

    You can coerce the passed array to an AS list:

    set inputValues to input as list
    

    Is it mostly planned to receive a single text input? Then go to Target/General, Input and Output options: com.apple.applescript.text-object or com.apple.cocoa.string These would be the class of the array items passed.