Is it possible to use multiple IF statements?

Hello there!

First of all I’ll explain my current situation - I’ve made an AI-like (Artificial Intelligence) application in pure applescript (before I decided to finally add a normal UI to it), which basically works in the following way: it displays a text field in a dialogue, checks which text was entered in it, sets a variable with this text, and then checks if it fits any “command”.
It has few dialogue commands which work the following way:

if firstquestion is in nice then
display dialog "How do you feel?" with icon file [icon path] default answer ""
                        set heyreply to text returned of result
                        if heyreply contains "great" then
                                display dialog "I'm glad! Mine was great too!" with icon file [icon path] default answer ""
                        else if heyreply contains "good" then
                                display dialog "Just good? Eh, I hope it gets better!" with icon file [icon path] default answer ""
                else if firstquestion is not in nice then
                end if

“nice” is a list variable which checks if the user was nice and contains words like “hey, hello, yo” etc.
It continues like that far down, with many more reactions.

I decided it’s time to move it to xCode in AppleScriptObjC format to add a better UI and make everything in the same window instead of using dozens of dialogue boxes.

What I did so far:
I’ve bound the property of the text field and set it to execute code when a button is being pressed, there’s the property “theCommand” which is bound to the text field and updates the value.
Then “set theText to theCommand() as text” sets it as variable…
By pressing the button called “Next” it executes the code which checks what string was entered (checks if variable is equal to a specific word), but the problem is… it can’t continue replying.

That’s how I managed to convert the IF reaction so far:

if theText is in nice
            theReaction's setStringValue_("How do you feel?")
            myImageWell's setImage_(iconHappy)
    end if

theReaction is a label, and myImageWell is an image well with icons (works by other variables I’ve defined above not mentioned in this post).

I tried to do something along of these lines:

        if theText is in nice
            theReaction's setStringValue_("How do you feel?")
            myImageWell's setImage_(iconHappy)
set goodDay to {"Great", "Good", "Perfect", "Amazing"}
if theText is in goodDay
display dialog "Works!"
end if
    end if

For testing purposes it was supposed to diaplay the dialog… but it didn’t.

Is there a way to make multiple IF statements in AppleScriptObjC? (If inside an If)

For example the AI greets the user, and asks him how he feels if the user replied. The user types a string such as “good” or “great”, and if the text field’s string value is equal to the string above (good or great, etc), it’ll display a reaction such as “My day was great too.”

I’ve managed to do it with two buttons but what I want is it being in one button. (Obviously in pure Applescript it works flawlessly as described above, but in xCode… not quite.)

And one smaller question - is it possible to set a default button that’ll be pressed every time I press enter? (like the default button function in an Applescript dialog box)?

Thanks for reading!

If statements work the same, whether it’s vanilla AppleScript or AppleScriptObjC. So yes, you can.

You set keyboard shortcuts for buttons in the Attributes Inspector.

Thanks about the keyboard answer :slight_smile:

About the IFs… the issue is that xCode executes the whole code all at once, so if I do this:

if theText is in nice
            theReaction's setStringValue_("How do you feel?")
            myImageWell's setImage_(iconHappy)
            if theText contains "good"
            display dialog "yay"
            end if
    end if

It basically doesn’t wait until the user answers again but checks if the field is equal to “good” at the same time I press the button the first time (so literally nothing happens), unlike in Applescript where it displays another dialog and answers according to the new string (or that’s how I think it works).

Is there some workaround? The textfield is set correctly - it does accept the new string, since if I do this but press another button instead with the following code:

if theText contains "good"
            display dialog "yay"
            end if

then it does display the dialog (or executes any other action which I put inside the IF).

Any idea what am I supposed to do in this case? I think it’s related to the fact I could define a new variable each time for the text returned and check it, but here I’m unsure how to do it correctly.

I’m sorry, but I can’t follow what you’re trying to achieve.

I’ll try to explain it in a better way - first of all I’m trying to make the script check for a specific word in a textfield, then if the word is found, it checks for another word, something like this:

if [the user wrote "hi" in the textfield]
[do something (which in my case is change a label; I was able to make it work so far)
[check] if [the user also writes another word, such as "good" at the same text field AFTER he wrote the first word and pressed the button for the first time]
[change the label again to something different]
end if
end if

The second label should appear only if the first word was found, and also the second word was found (after pressing the button the first time, and then the second time)
It does recognize the first word, which is “hi” or “hello”, but it doesn’t recognize the second word.

I’m still lost. When the user presses a button that triggers a handler, that handler runs to completion, and anything the user tries to do in the UI will be queued until then.

I recorded a video of my Applescript:
https://dl.dropboxusercontent.com/u/49253987/MyScript.mp4
This is pretty much what I’m trying to convert to ASobjC now…
my textfield property is called “textField” and the entered string in the textfield is called “theText”

The script is being relaunched in the middle as you can see… so it basically shows different reaction for different entered strings.

Any idea how can I do it?

It looks like you need to store the first word in a property. Then you can check the property, to see what to do next.

This is pretty much what I did in the beginning, but I still can’t get it to work. Can you please look at my code and tell me what’s wrong?

property textField : missing value
property theText : ""
    
on buttonClicked_(sender)

[some icon variables are present here]

set theText to textField's stringValue() as text
        		set nice to {"Hey", "Hello", "Yo", "Sup"}
        		set goodDay to {"Great", "Good", "Perfect", "Amazing"}

        		if theCommand is in nice
        			[here goes code of changing the label & setting icon]
        			if theText is in goodDay
        			[changing label again & setting different icon]
        end if
end if

        	end buttonClicked_

I edited out some of the code to avoid making it long; anyway it recognizes the words in “nice” but it just skips whatever is in “goodDay”.

Thank you for your time of reading my messages!

is the text field connected to the property textField in Interface Builder?
You can use the log command to print out variable values, for example

set theText to textField's stringValue() as text
log theText

Yeah it was connected… that’s why the first word was recognized at all.
I somehow managed to make it work just few minutes ago with booleans:

if theText is in nice
[changing label & setting icon]
        end if
            if theText is in goodDay
            set hadGoodDay to true
            if hadGoodDay is true
[changing label again and setting icon]
    end if
            else if theText is in badDay
            set hadGoodDay to false
if theText is in badDay
[changing label to something else and setting another icon]
end if
            end if

…That took some time. I can’t believe that I couldn’t think about this sooner. :confused:

Thanks for the log tip!
I have one last question/issue - if I use a longer code with delays, such as this:

myImageWell's setImage_(icon1)
theReaction's setStringValue_("Text")
delay 3
myImageWell's setImage_(icon2)
theReaction's setStringValue_("Text2")
delay 3
myImageWell's setImage_(icon3)
theReaction's setStringValue_("Text3")

If I move my mouse even one pixel (whether its in the window or not) while it runs, then it just fast-forwards the whole code (changes the text & the icon three times in under a second) and completely ignores the delays. Is there some setting to let it use the delays? Maybe some kind of running in background setting?

this is supposed to work too


if theText is in nice then
	-- [changing label & setting icon]
end if
if theText is in goodDay then
	-- [changing label again and setting icon]
else if theText is in badDay then
	-- [changing label to something else and setting another icon]
end if

For the delays better use the method performSelector:withObject:afterDelay: for example


my performSelector:"updateIconAndReaction1" withObject:(missing value) afterDelay:3.0

on updateIconAndReaction1()
	myImageWell's setImage:icon1
	theReaction's setStringValue:"Text"
	my performSelector:"updateIconAndReaction2" withObject:(missing value) afterDelay:3.0
end updateIconAndReaction1

on updateIconAndReaction2()
	myImageWell's setImage:icon2
	theReaction's setStringValue:"Text2"
end updateIconAndReaction2


So the actual IF script was that simple and I just overthought it… oh well.
The delays work flawlessly now, thank you :slight_smile: