Jake3231

Q: Applescript and interface won't run together

I am creating a Cocoa Applescript application, and I have an applescript to make speech recognition server listen for commands to use as input.  I also have a small window that should appear at the top.  When I run the application, the speech recognition window appears and works like it is supposed to.  Sometimes the window I created doesn't show up until I quit the applescript part of the program, or it is gray and unusable until I quit the applescript part.  I want them to run side-by-side.  I am aiming for the speech recognition window appearing like normal, and the other window appearing at the same time (or close to the same time) and both working.

MacBook Pro, OS X Mavericks (10.9)

Posted on Oct 26, 2013 12:57 PM

Close

Q: Applescript and interface won't run together

  • All replies
  • Helpful answers

Page 1 of 4 last Next
  • by red_menace,Helpful

    red_menace red_menace Oct 26, 2013 1:16 PM in response to Jake3231
    Level 6 (15,541 points)
    Desktops
    Oct 26, 2013 1:16 PM in response to Jake3231

    It sounds like your script is blocking the user interface, but without seeing some code it is hard to tell.  If you are using somethng like a repeat statement that doesn't exit until it is done, events such as button presses and window updates will get backed up in the event queue until the run loop is given time to process them.

     

    You can add a handler to manually process events, but the best approach would be to take a look at your code and use the appropriate delegate/callback methods or break it up so that the system is given time to update the interface.

  • by Jake3231,

    Jake3231 Jake3231 Oct 26, 2013 1:37 PM in response to red_menace
    Level 1 (68 points)
    Oct 26, 2013 1:37 PM in response to red_menace

    I am using a repeat loop. Here is my code! Or my app delegate to be more exact.

     

     

    --

    --  AAAppDelegate.applescript

     

    script AAAppDelegate

              property parent : class "NSObject"

     

              on applicationWillFinishLaunching:aNotification

                        try

                                  set startvol to do shell script "cat ~/alphaassistantdata/startvol.txt "

      set volume output volume startvol

                        end try

                        set shouldseyi to "Yes"

                        set mc1 to "false"

                        set mcexists to get "Minecraft.app"

                        try

     

                                  do shell script "ping -o www.apple.com"

                                  set isonline to "true"

                        on error

                                  set isonline to "false"

                        end try

                        set sysinfo to system info

                        set osver to system version of sysinfo

                        set ver to "1.2.1"

                        set shouldwearing to "0"

      --get web's version

                        if isonline is "true" then

                                  set webver to do shell script "curl http://alphateam2.weebly.com/uploads/1/2/2/1/12215941/version.txt"

                                  tell application "Finder"

                                            if ver is greater than webver then

                                            else

                                                      set shouldupdate to the button returned of (display dialog "You are running an outdated version of Alpha Assistant. Version " & webver & " is available.  Would you like to download the update? " buttons {"Yes", "No"})

                                                      if shouldupdate is "Yes" then

                                                                tell application "Finder" to set the clipboard to "http://alphateam2.weebly.com/uploads/1/2/2/1/12215941/alpha_assistant.zip"

                                                                tell application "System Events"

                                                                          tell application "Safari" to activate

      keystroke "l" using {command down, option down}

      keystroke "v" using command down

                                                                          move file "AlphaAssistant.zip" of "Downloads" to desktop

                                                                end tell

                                                      end if

     

                                            end if

                                  end tell

                        end if

              end applicationWillFinishLaunching:

     

              on applicationDidFinishLaunching:aNotification

     

     

              end applicationDidFinishLaunching:

     

              on applicationShouldTerminate:sender

      -- Insert code here to do any housekeeping before your application quits

                        return current application's NSTerminateNow

              end applicationShouldTerminate:

     

    end script

  • by red_menace,

    red_menace red_menace Oct 26, 2013 1:44 PM in response to Jake3231
    Level 6 (15,541 points)
    Desktops
    Oct 26, 2013 1:44 PM in response to Jake3231

    I'm not seeing a repeat statement or anything to do with speech recognition in your posted code.  In general, just dropping a regular AppleScript into an Xcode project isn't really the way to go - for example note that the applicationWillFinishLaunching method is called right before your application is initialized, so some things may not be ready or available yet.

  • by Jake3231,

    Jake3231 Jake3231 Oct 26, 2013 1:50 PM in response to red_menace
    Level 1 (68 points)
    Oct 26, 2013 1:50 PM in response to red_menace

    whoops.  Sorry.  that is the wrong code.  The code I just posted was some startup code.  It's also in this script. This is the right code. Its a bit long.

     

     

    try

              set startvol to do shell script "cat ~/alphaassistantdata/startvol.txt "

      set volume output volume startvol

    end try

    set shouldseyi to "Yes"

    set mc1 to "false"

    set mcexists to get "Minecraft.app"

    try

     

              do shell script "ping -o www.apple.com"

              set isonline to "true"

    on error

              set isonline to "false"

    end try

    set sysinfo to system info

    set osver to system version of sysinfo

    set ver to "1.2.1"

    set shouldwearing to "0"

    --get web's version

    if isonline is "true" then

              set webver to do shell script "curl http://alphateam2.weebly.com/uploads/1/2/2/1/12215941/version.txt"

              tell application "Finder"

                        if ver is greater than webver then

                        else

                                  set shouldupdate to the button returned of (display dialog "You are running an outdated version of Alpha Assistant. Version " & webver & " is available.  Would you like to download the update? " buttons {"Yes", "No"})

                                  if shouldupdate is "Yes" then

                                            tell application "Finder" to set the clipboard to "http://alphateam2.weebly.com/uploads/1/2/2/1/12215941/alpha_assistant.zip"

                                            tell application "System Events"

                                                      tell application "Safari" to activate

      keystroke "l" using {command down, option down}

      keystroke "v" using command down

                                                      move file "AlphaAssistant.zip" of "Downloads" to desktop

                                            end tell

                                  end if

     

                        end if

              end tell

    end if

    repeat

              try

                        do shell script "ping -o www.apple.com"

                        set isonline to "true"

              on error

                        set isonline to "false"

              end try

     

     

              if isonline is "true" then

                        set CityCode to 2424766

      --temperature format

                        set t_format to "F"

      --voiceover format

                        set v_format to "S"

      --say present condition

                        set a_format to "Y"

     

                        set IURL to "http://weather.yahooapis.com/forecastrss?w=" & CityCode

                        set file_content to (do shell script "curl " & IURL)

      --looking for the line with actual condition

                        set theText to text ((offset of "yweather:condition" in file_content) + 1) thru -1 of file_content

                        set sub_1 to text ((offset of "\"" in theText) + 1) thru -1 of theText

     

      --today conditions found

                        set actual_condition to text 1 thru ((offset of "\"" in sub_1) - 1) of sub_1

     

      --looking for actual temperature temperature

                        set sub_1a to text ((offset of "temp=" in sub_1)) thru -1 of sub_1

                        set sub_1b to text ((offset of "\"" in sub_1a) + 1) thru -1 of sub_1a

                        set actual_temp to text 1 thru ((offset of "\"" in sub_1b) - 1) of sub_1b

     

                        if t_format is equal to "C" then

                                  set actual_temp to (5 / 9) * (actual_temp - 32) as integer

                        end if

      --looking for today forecast

                        set theText to text ((offset of "yweather:forecast" in file_content) + 1) thru -1 of file_content

                        set sub_2 to text ((offset of "\"" in theText) + 1) thru -1 of theText

      --looking for today forecast condition (a bit tricky)

                        set sub_3 to text ((offset of "text" in sub_2) + 1) thru -1 of sub_2

                        set sub_4 to text ((offset of "\"" in sub_3) + 1) thru -1 of sub_3

                        set today_forecast to text 1 thru ((offset of "\"" in sub_4) - 1) of sub_4

              end if

              set doesexist to "true"

              set alphausername to do shell script "cat ~/alphaassistantdata/name.txt "

              tell application "SpeechRecognitionServer"

      activate

              end tell

              try

                        if shouldseyi is "yes" then

                                  say "Hello!  What could I do for you, " & alphausername & "? "

                                  set shouldseyi to "no"

                        end if

              on error

                        say "Hello! What could I do for you?"

              end try

              tell application "SpeechRecognitionServer" to set theResponse to listen for {"Leave", "Hi", "Show me mr.Krol's website", "Report a bug", "Leave", "Open Mr.Krol's website", "Edmodo", "Open Edmodo", "You're Awesome", "IXL", "I found a bug", "What is your name", "What is the weather like", "thankyou", "Am I making good grades", "How are my grades", " Leave now", "Go to MMS website", "MMS", "SBISD", "Go to SBISD website", "Open IXL", "Show me the math textbook", "Math textbook", "Hello", "Thanks", "What's the weather like", "What is the weather like", "AlphaAssistant", "Good", "Thats Good", "Open iMovie", "Edit a video", "You're Evil", "You are evil", "Open Awesomeware", "Open AlphaTeam", "Open Minecraft", "goodbye", "Safari", "Open Safari", "You're Ugly", "You are ugly", "Where do you live", "Shutup", "Listen", "Listen to me", "What is my name", "Who am I", "Call me something else", "You're nice", "You are nice", "Okay", "Hows you're day", "Who are you", "Do you know Siri", "Testing 1234", "What is your favorite team", "SkyDoesMinecraft", "I love you", "Iron hand", "Do you know iron hand", "Should I wear shorts", "Test for connection", "What is the Temprature", "What version am I running", "Resset my volume", "You can talk now"} displaying "Version 1.0" with prompt ""

      --Bug Report

              if theResponse is "Report a bug" or theResponse is "I found a bug" then

                        say "You can send bug reports to us through our contact page.  Would you like to go there?"

                        tell application "SpeechRecognitionServer" to set theResponse to listen for {"yes", "No"}

                        set openbugsite to "1"

                        if openbugsite is "1" and theResponse is "Yes" then

                                  tell application "Safari"

                                            say "Okay.  I'll open up our contact page."

                                            open location "http://alphateam2.weebly.com/contact.html"

                                            set openbugsite to "0"

                                  end tell

                        end if

              end if

              if theResponse is "No" then

                        say "Okay.  I won't open the contact page."

              end if

      --Show Mr.Krol's Site

              if theResponse is "Show me mr.Krol's website" or theResponse is "Open Mr.krol's website" then

                        say "i will show you Mister krol's website"

                        tell application "Safari"

                                  open location "http://mms.springbranchisd.com/Staff/Teachers/Mathematics/JackKrol6thGrade/tabid /29065/Default.aspx"

                        end tell

              end if

      --Respond to "hello"

              if theResponse is "Hi" or theResponse is "Hello" then

                        say "Alpha Assistant says hi"

              end if

      --Leave command

              if theResponse is "Leave" or theResponse is "Leave now" or theResponse is "kill" or theResponse is "goodbye" then

                        say "okay.  Bye"

                        tell application "SpeakableItems"

      quit

                        end tell

                        exit repeat

                        tell me to quit

     

     

              end if

      --Edmodo

              if theResponse is "Edmodo" then

                        tell application "Safari"

                                  say "I'll open Edmodo."

                                  open location "http://www.edmodo.com"

                        end tell

              end if

      --Respond to "You're Awesome" command

              if theResponse is "You're awesome" then

                        say "Thanks!  You're pretty cool yourself!"

              end if

      --Open Edmodo

              if theResponse is "Open Edmodo" then

                        say "I'll open Edmodo"

                        tell application "Safari"

                                  open location "http://www.edmodo.com"

                        end tell

              end if

      --Response to "what is your name command"

              if theResponse is "What is your name" or theResponse is "Who are you" then

                        say "My name is Alpha Assistant."

              end if

      --Response to "what is the weather like command"

              if theResponse is "What is the weather like" or theResponse is "What's the weather like" then

      --this is the city code. Search the code for your city on http://weather.yahoo.com/

                        set CityCode to 2424766

      --temperature format

                        set t_format to "F"

      --voiceover format

                        set v_format to "S"

      --say present condition

                        set a_format to "Y"

     

                        set IURL to "http://weather.yahooapis.com/forecastrss?w=" & CityCode

     

      --downloading the file using curl

                        set file_content to (do shell script "curl " & IURL)

      --looking for the line with actual condition

                        set theText to text ((offset of "yweather:condition" in file_content) + 1) thru -1 of file_content

                        set sub_1 to text ((offset of "\"" in theText) + 1) thru -1 of theText

     

      --today conditions found

                        set actual_condition to text 1 thru ((offset of "\"" in sub_1) - 1) of sub_1

     

      --looking for actual temperature temperature

                        set sub_1a to text ((offset of "temp=" in sub_1)) thru -1 of sub_1

                        set sub_1b to text ((offset of "\"" in sub_1a) + 1) thru -1 of sub_1a

                        set actual_temp to text 1 thru ((offset of "\"" in sub_1b) - 1) of sub_1b

     

                        if t_format is equal to "C" then

                                  set actual_temp to (5 / 9) * (actual_temp - 32) as integer

                        end if

     

      --looking for today forecast

                        set theText to text ((offset of "yweather:forecast" in file_content) + 1) thru -1 of file_content

                        set sub_2 to text ((offset of "\"" in theText) + 1) thru -1 of theText

     

      --maximum and minimum temperatures found

                        set today_min_temp to word 9 of sub_2

                        set today_max_temp to word 12 of sub_2

                        if t_format is equal to "C" then

                                  set today_min_temp to (5 / 9) * (today_min_temp - 32) as integer

                                  set today_max_temp to (5 / 9) * (today_max_temp - 32) as integer

                        end if

     

      --looking for today forecast condition (a bit tricky)

                        set sub_3 to text ((offset of "text" in sub_2) + 1) thru -1 of sub_2

                        set sub_4 to text ((offset of "\"" in sub_3) + 1) thru -1 of sub_3

                        set today_forecast to text 1 thru ((offset of "\"" in sub_4) - 1) of sub_4

     

      --looking for tomorrow forecast

                        set sub_5 to text ((offset of "yweather:forecast" in sub_4) + 1) thru -1 of sub_4

                        set sub_6 to text ((offset of "\"" in sub_5) + 1) thru -1 of sub_5

     

      --maximum and minimum temperatures found

                        set tomorrow_min_temp to word 9 of sub_6

                        set tomorrow_max_temp to word 12 of sub_6

                        if t_format is equal to "C" then

                                  set tomorrow_min_temp to (5 / 9) * (tomorrow_min_temp - 32) as integer

                                  set tomorrow_max_temp to (5 / 9) * (tomorrow_max_temp - 32) as integer

                        end if

     

      --looking for tomorrow forecast condition (a bit tricky)

                        set sub_7 to text ((offset of "text" in sub_6) + 1) thru -1 of sub_6

                        set sub_8 to text ((offset of "\"" in sub_7) + 1) thru -1 of sub_7

                        set tomorrow_forecast to text 1 thru ((offset of "\"" in sub_8) - 1) of sub_8

     

      --VoiceOver Section

                        set myTime to time string of (current date)

                        set myParts to words of myTime

                        set mySpeak to (item 1 of myParts) & " " & (item 2 of myParts) & " "

                        if a_format is equal to "Y" then

                                  say "Outside it is, " & actual_condition & ", and " & actual_temp & " degrees "

                        end if

                        if v_format is equal to "L" then

                                  say "Today: " & today_forecast & ". Temperature: between " & today_min_temp & " and " & today_max_temp & " degrees.

              Tomorrow: " & tomorrow_forecast & ". Temperature: between " & today_min_temp & " and " & today_max_temp & " degrees"

                        else

                                  say "Today: " & today_forecast & ", between " & today_min_temp & " , and " & today_max_temp & " degrees.

               Tomorrow: " & tomorrow_forecast & ", between " & tomorrow_min_temp & " ,and " & tomorrow_max_temp & " degrees"

                        end if

              end if

      --Response to thankyou

              if theResponse is "thankyou" or theResponse is "thanks" then

                        say "My pleasure"

              end if

      --Respond to "how are my grades"

              if theResponse is "Am I making good grades" or theResponse is "How are my grades" then

                        say "I can not tell you your grades, but I can show you them on Skyward.  Would you like me to go to Skyward?"

                        tell application "SpeechRecognitionServer" to set theResponse to listen for {"yes", "No"}

                        set openskyward to "1"

                        if openskyward is "1" and theResponse is "Yes" then

                                  tell application "Safari"

                                            say "Okay.  I'll open Skyward.  Please enter your Springbranch login info if you have not run the installer"

                                            if doesexist is "true" then

                                                      set username2 to do shell script "cat ~/alphaassistantdata/username.txt "

                                            else

                                                      set username2 to the text returned of (display dialog "Please enter your springbranch username." default answer "")

                                            end if

     

                                            if doesexist is "true" then

                                                      set password2 to do shell script "cat ~/alphaassistantdata/password.txt "

                                            else

                                                      set password2 to the text returned of (display dialog "Please enter your springbranch password" default answer "")

                                            end if

     

                                            open location "https://skyward.springbranchisd.com/"

                                            tell application "System Events"

                                                      delay 2

     

      keystroke username2

                                            end tell

                                            tell application "System Events"

      keystroke tab

                                            end tell

                                            tell application "System Events"

      keystroke password2

                                            end tell

                                            tell application "System Events"

      keystroke return

                                            end tell

     

     

                                            set openskyward to "3"

                                  end tell

                        end if

              end if

              if theResponse is "No" and openskyward is "3" then

                        say "Okay.  I won't open Skyward."

              end if

      -- go to MMS site

              if theResponse is "MMS" or theResponse is "Go to MMS website" then

                        say "I'll go to the MMS Website."

                        tell application "Safari"

                                  open location "http://mms.springbranchisd.com"

                        end tell

              end if

      --Go to SBISD site

              if theResponse is "SBISD" or theResponse is "Go the the SBISD website" then

                        say "I'll go to the SBISD website"

                        tell application "Safari"

                                  open location "http://www.springbranchisd.com"

                        end tell

              end if

              if theResponse is "IXL" or theResponse is "Open IXL" then

                        say "I'll open IXL"

                        tell application "Safari"

                                  open location "www.ixl.com"

                        end tell

              end if

              if theResponse is "Show me the math textbook" or theResponse is "Math textbook" then

                        say "Okay, I'll show you the math textbook"

                        tell application "Safari"

                                  open location "http://www.glencoe.com/ose/showbook.php"

                        end tell

              end if

      --AlphaAssistant

              set alphaassistant to {"Thats me!", "Yes?", "AlphaAssistant here!"}

              if theResponse is "AlphaAssistant" then

      say some item of alphaassistant

              end if

      --Good

              if theResponse is "good" or theResponse is "thats good" then

                        say "it is"

              end if

              if theResponse is "open iMovie" or theResponse is "Edit a video" then

                        tell application "iMovie"

                        end tell

              end if

      -- open alphateam

              if theResponse is "open alphateam" then

                        say "I'll open Alpha Team's website"

                        tell application "Safari"

                                  open location "http://www.alphateam2.weebly.com"

                        end tell

              end if

      -- Open Awesomeware

              if theResponse is "Open Awesomeware" then

                        say "I'll open Awesomeware"

                        tell application "Safari"

                                  open location "http://www.awesomeware.weebly.com"

                        end tell

              end if

      --random person like reposonses

              if theResponse is "you're evil" or theResponse is "You are evil" then

                        say "what did I do?"

              end if

              if theResponse is "You're ugly" or theResponse is "You are ugly" then

                        say "Thats not nice…"

              end if

              if theResponse is "Where do you live" then

                        say "I live on your Mac, and lots of student's Macs"

              end if

              if theResponse is "Shutup" then

                        set currentVolume to output volume of (get volume settings)

      set volume 0

                        say "Okay"

              end if

              if theResponse is "Listen to me" or theResponse is "Listen" then

                        say "I'm listening"

              end if

              if theResponse is "You're nice" or theResponse is "You are nice" then

                        say "Thanks!"

              end if

              if theResponse is "Okay" then

                        say "Okay"

              end if

              if theResponse is "How is you're day" or theResponse is "Hows you're day" then

                        say "It is great!  Thanks for asking."

              end if

              if theResponse is "Do you know Siri" then

                        say "Yes…"

              end if

              if theResponse is "Testing 1234" then

                        say "Im am ready to assist"

              end if

              if theResponse is "I love you" then

                        say "Um… Thanks?"

              end if

              if theResponse is "iron hand" or theResponse is "Do you know iron hand" then

                        say "I don't like iron hand"

              end if

      -- Open Minecraft

              if theResponse is "open Minecraft" and mcexists is "true" then

                        set mc1 to "true"

                        say "I'll open Minecraft"

                        tell application "Minecraft"

      activate

                        end tell

              else

                        if mc1 is "true" then

                                  say "It looks like you don't have Minecraft"

                        end if

                        set mc1 to "False"

              end if

      -- Open Safari

              if theResponse is "open Safari" or theResponse is "Safari" then

                        say "I'll open Safari"

                        tell application "Safari"

      activate

                        end tell

              end if

      -- what is my name

              if theResponse is "What is my name" or theResponse is "Who am I" then

                        try

                                  say "You're name is " & alphausername & " "

                        on error

                                  say "It appears that I don't know your name, Would you like to tell me?"

                                  tell application "SpeechRecognitionServer" to set getnamea to listen for {"Yes", "No"}

                                  if getnamea is "Yes" then

                                            set alphausername to the text returned of (display dialog "What is you're name?" default answer "")

                                            say "I'll call you " & alphausername & " "

                                            do shell script "echo " & alphausername & " > $HOME/alphaassistantdata/name.txt"

                                  end if

                        end try

              end if

      --Call me something else

              if theResponse is "Call me something else" then

                        say "What would you like me to call you?"

                        set alphausername to the text returned of (display dialog "What would you like me to call you?" default answer "" buttons {"Okay"})

                        say "I'll call you " & alphausername & " "

                        do shell script "echo " & alphausername & " > $HOME/alphaassistantdata/name.txt"

              end if

              if theResponse is "what is your favorite team" then

                        say "My favorite team is Texas A&M"

              end if

              if theResponse is "SkyDoesMinecraft" then

                        say "I'll open Sky's website"

                        tell application "Safari"

                                  open location "http://www.skydoesminecraft.com"

                        end tell

              end if

      --Should I wear

              try

                        if theResponse is "should I wear shorts" then

                                  set shouldwearing to "1"

                                  if actual_temp < 70 then

                                            say "no, today would not be a good day to wear shorts."

                                  else

                                            say "Yes, today would be a good day to wear shorts."

                                  end if

                        end if

              on error

                        if shouldwearing is "1" then

                                  say "Please connect to the internet to use this feature"

                        end if

                        set shouldwearing to "0"

     

              end try

      --Test for connection

              if theResponse is "Test for Connection" then

                        try

                                  do shell script "ping -o www.apple.com"

                                  set isonline to "true"

                        on error

                                  set isonline to "false"

                        end try

                        if isonline is "true" then

                                  say "I found a network"

                        else

                                  say "I did not find a network"

                        end if

              end if

              if theResponse is "What is the Temprature" then

                        say "it is " & actual_temp & " degrees outside"

              end if

              if theResponse is "what version am I running" then

                        say "you are running Alpha Assistant version  " & ver & " "

              end if

              if theResponse is "Reset my volume" or theResponse is "You can talk now" then

      set volume currentVolume

                        say "Okay!"

              end if 

    end repeat


  • by red_menace,Helpful

    red_menace red_menace Oct 26, 2013 2:03 PM in response to Jake3231
    Level 6 (15,541 points)
    Desktops
    Oct 26, 2013 2:03 PM in response to Jake3231

    I'm not seeing any window or other Cocoa methods, but you definitely need to break this up into several smaller handlers rather than one monolithic script.

     

    Cocoa has an NSSpeechRecognitionServer class that will call a delegate method so that you can do other things while waiting for a response - is there a particular reason you are wanting to use an Xcode project with this?

  • by Jake3231,

    Jake3231 Jake3231 Oct 26, 2013 2:47 PM in response to red_menace
    Level 1 (68 points)
    Oct 26, 2013 2:47 PM in response to red_menace

    I have all the windows in an xib file.  I'll have to check out NSSSpechRecognitionServer.  Thanks for telling me about that!  I wanted to use Xcode to add a GUI.  Before, it was just an applescript application.  I want to add a nice window/toolbar.  Thanks!

  • by red_menace,Solvedanswer

    red_menace red_menace Oct 26, 2013 2:54 PM in response to Jake3231
    Level 6 (15,541 points)
    Desktops
    Oct 26, 2013 2:54 PM in response to Jake3231

    I think if you use NSSpeechRecognizer to start listening for your terms, and then break up the various recognized ones from the speechRecognizer:didRecognizeCommand: delegate method, you should be able to keep the user interface responsive.

  • by Jake3231,

    Jake3231 Jake3231 Oct 26, 2013 3:04 PM in response to red_menace
    Level 1 (68 points)
    Oct 26, 2013 3:04 PM in response to red_menace

    Thanks!  I have looked into that, and I think I will use it.  Just wondering, does Apple provide a sample xcode project?  

  • by Jake3231,

    Jake3231 Jake3231 Oct 26, 2013 6:31 PM in response to red_menace
    Level 1 (68 points)
    Oct 26, 2013 6:31 PM in response to red_menace

    I have tried that, but Xcode keeps giving me errors...  If I removed the repeat loop in the applescript, could they run side-by-side?

  • by red_menace,

    red_menace red_menace Oct 26, 2013 7:28 PM in response to Jake3231
    Level 6 (15,541 points)
    Desktops
    Oct 26, 2013 7:28 PM in response to Jake3231

    AppleScript (and Objective-C, for that matter) in Xcode runs a bit differently than a regular AppleScript.  A regular AppleScript assumes something like your original post, where the script runs in a more-or-less linear fashon from start to finish, and if you need to do it again just start over.  In Xcode, there is a user interface to consider, and since the user can use this interface in different ways, the application needs to be constucted to be run in response to various events in real time (more or less) - there really isn't a given sequence.

     

    In your original posted script, all of the listen/respond events are in one big linear loop, which doesn't really go with Cocoa's object oriented design, so I would start by splitting up the various operations.  This also tends to have the effect of giving the run loop places to sneak in there to do its thing in addition to making your project easier to scale and maintain.

     

    It sounds like you don't quite have a handle on NSSpeechRecognizer.  You should look into not using a repeat statement at all - the recognizer engine will run asynchronously in the background, and call a delegate method when a command is recognized, so just initialize a recognizer and turn it loose with the commands to listen for.  The speechRecognizer:didRecognizeCommand: delegate method can then call the appropriate response handler using the command that was recognized.

  • by Jake3231,

    Jake3231 Jake3231 Oct 27, 2013 6:26 AM in response to red_menace
    Level 1 (68 points)
    Oct 27, 2013 6:26 AM in response to red_menace

    Okay...  I have tried that, and sucessfuly compiled some code.  They only problem is I don't think it's listening to me.  I created a few random commands for it to listen for.  It should print what it hears to the console.  Is this right?

     

    (.m)

     

     

    #import "SpeechRecAppDelegate.h"

    #import <AppKit/AppKit.h>

     

    @implementation AAAppDelegate

     

    @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

    @synthesize managedObjectModel = _managedObjectModel;

    @synthesize managedObjectContext = _managedObjectContext;

     

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification

    {

        // Insert code here to initialize your application

    }

     

    // Returns the directory the application uses to store the Core Data store file. This code uses a directory named "JakeSpann.test" in the user's Application Support directory.

    - (NSURL *)applicationFilesDirectory

    {

        NSFileManager *fileManager = [NSFileManager defaultManager];

        NSURL *appSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];

        return [appSupportURL URLByAppendingPathComponent:@"JakeSpann.test"];

    }

     

    // Creates if necessary and returns the managed object model for the application.

    - (NSManagedObjectModel *)managedObjectModel

    {

        if (_managedObjectModel) {

            return _managedObjectModel;

        }

     

        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"momd"];

        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

        return _managedObjectModel;

    }

     

    // Returns the persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.)

    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator

    {

        if (_persistentStoreCoordinator) {

            return _persistentStoreCoordinator;

        }

       

        NSManagedObjectModel *mom = [self managedObjectModel];

        if (!mom) {

            NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));

            return nil;

        }

       

        NSFileManager *fileManager = [NSFileManager defaultManager];

        NSURL *applicationFilesDirectory = [self applicationFilesDirectory];

        NSError *error = nil;

       

        NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:@[NSURLIsDirectoryKey] error:&error];

       

        if (!properties) {

            BOOL ok = NO;

            if ([error code] == NSFileReadNoSuchFileError) {

                ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error];

            }

            if (!ok) {

                [[NSApplication sharedApplication] presentError:error];

                return nil;

            }

        } else {

            if (![properties[NSURLIsDirectoryKey] boolValue]) {

                // Customize and localize this error.

                NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]];

               

                NSMutableDictionary *dict = [NSMutableDictionary dictionary];

                [dict setValue:failureDescription forKey:NSLocalizedDescriptionKey];

                error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict];

               

                [[NSApplication sharedApplication] presentError:error];

                return nil;

            }

        }

       

        NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"test.storedata"];

        NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];

        if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]) {

            [[NSApplication sharedApplication] presentError:error];

            return nil;

        }

        _persistentStoreCoordinator = coordinator;

       

        return _persistentStoreCoordinator;

    }

     

    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)

    - (NSManagedObjectContext *)managedObjectContext

    {

        if (_managedObjectContext) {

            return _managedObjectContext;

        }

       

        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

        if (!coordinator) {

            NSMutableDictionary *dict = [NSMutableDictionary dictionary];

            [dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey];

            [dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey];

            NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];

            [[NSApplication sharedApplication] presentError:error];

            return nil;

        }

        _managedObjectContext = [[NSManagedObjectContext alloc] init];

        [_managedObjectContext setPersistentStoreCoordinator:coordinator];

     

        return _managedObjectContext;

    }

     

    // Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application.

    - (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window

    {

        return [[self managedObjectContext] undoManager];

    }

     

    // Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user.

    - (IBAction)saveAction:(id)sender

    {

        NSError *error = nil;

       

        if (![[self managedObjectContext] commitEditing]) {

            NSLog(@"%@:%@ unable to commit editing before saving", [self class], NSStringFromSelector(_cmd));

        }

       

        if (![[self managedObjectContext] save:&error]) {

            [[NSApplication sharedApplication] presentError:error];

        }

    }

     

    - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender

    {

        // Save changes in the application's managed object context before the application terminates.

       

        if (!_managedObjectContext) {

            return NSTerminateNow;

        }

       

        if (![[self managedObjectContext] commitEditing]) {

            NSLog(@"%@:%@ unable to commit editing to terminate", [self class], NSStringFromSelector(_cmd));

            return NSTerminateCancel;

        }

       

        if (![[self managedObjectContext] hasChanges]) {

            return NSTerminateNow;

        }

       

        NSError *error = nil;

        if (![[self managedObjectContext] save:&error]) {

     

            // Customize this code block to include application-specific recovery steps.             

            BOOL result = [sender presentError:error];

            if (result) {

                return NSTerminateCancel;

            }

     

            NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message");

            NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info");

            NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title");

            NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title");

            NSAlert *alert = [[NSAlert alloc] init];

            [alert setMessageText:question];

            [alert setInformativeText:info];

            [alert addButtonWithTitle:quitButton];

            [alert addButtonWithTitle:cancelButton];

     

            NSInteger answer = [alert runModal];

           

            if (answer == NSAlertAlternateReturn) {

                return NSTerminateCancel;

            }

        }

     

        return NSTerminateNow;

    }

     

    @end

     

    @implementation SpeechRecAppDelegate : NSObject

     

    @synthesize window;

     

    - (id)init {

        self = [super init];

        if (self) {

            NSArray *cmds = [NSArray arrayWithObjects:@"Forward",

                                                                 @"Stop", @"Left", @"Right", @"Backwards", @"Roll over", nil];

            recog = [[NSSpeechRecognizer alloc] init]; // recog is an ivar

            [recog setCommands:cmds];

            [recog setDelegate:self];

        }

        return self;

    }

    -(void)speechRecognizer:(NSSpeechRecognizer *)sender

        didRecognizeCommand:(id)aCmd {

     

              if ([(NSString *)aCmd isEqualToString:@"Forward"]) {

      NSLog(@"Forward called");

      return;

        }

     

        else if ([(NSString *)aCmd isEqualToString:@"Stop"]) {

      NSLog(@"Stop called");

            return;

        }

        else if ([(NSString *)aCmd isEqualToString:@"Roll over"]) {

      NSLog(@"Rollover called");

           

        }

      else {

      NSLog(@"hello");

              }

     

     

    (.h)

    #import <Cocoa/Cocoa.h>

    #import <AppKit/AppKit.h>

    @interface AAAppDelegate : NSObject <NSApplicationDelegate>

     

    @property (assign) IBOutlet NSWindow *window;

     

    @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

    @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;

    @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;

     

    - (IBAction)saveAction:(id)sender;

     

    @end

    #import <Cocoa/Cocoa.h>

     

    @interface SpeechRecAppDelegate : NSObject <NSSpeechRecognizerDelegate>  {

        NSWindow *test;

      NSSpeechRecognizer* recog;

    }

     

     

     

    @property (assign) IBOutlet NSWindow *window;

     

    @end

  • by red_menace,

    red_menace red_menace Oct 27, 2013 7:41 AM in response to Jake3231
    Level 6 (15,541 points)
    Desktops
    Oct 27, 2013 7:41 AM in response to Jake3231

    I don't know ObjC that well (it was looking like you were going to be using AppleScript), but it doesn't look like you have told the speech recognizer to actually start listening.

  • by red_menace,

    red_menace red_menace Oct 27, 2013 9:59 PM in response to Jake3231
    Level 6 (15,541 points)
    Desktops
    Oct 27, 2013 9:59 PM in response to Jake3231

    OK, I've uploaded an example AppleScriptObjC project with some of your commands - it can be downloaded here.  There is a window with a popup button to manually test some of the commands, and it uses a speech synthesizer instead of the say command (the say command blocks the UI).

     

    The approach I used is to load the various commands and the selectors for their response handlers from a property list file into a dictionary - there are most likely better approaches, but this way allows for fairly easy editing of the command list and gets rid of all those if statements by placing the response code for a command into its own handler.  You will also notice that there are no repeat statements.

     

    Some tweaking will probably still need to be done depending on how you want to do some of the more conversational parts, but I was surprised at how well it works - gotta love that Cocoa.

  • by Jake3231,

    Jake3231 Jake3231 Oct 28, 2013 6:44 PM in response to red_menace
    Level 1 (68 points)
    Oct 28, 2013 6:44 PM in response to red_menace

    Thanks! That is awesome!

Page 1 of 4 last Next