I got quite stuck in many ways with ASOC. I thought it may be beneficial to post a tutorial of things I would have found very useful back then for others beginning now.
The script you will use is named [your app name]AppDelegate.applescript in the project library.
Firstly change
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return my NSTerminateNow
end applicationShouldTerminate_
to
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return (current application's NSTerminateNow) as integer
end applicationShouldTerminate_
In AppleScript Obj-C everything GUI related must have a link to your code to do this start off with
property parent : class "NSObject"
(to be honest Iâm not sure why, this is what I know) then add property [your variable name] : missing value below for each GUI object you wish to interact with later in your code e.g.
property valwintext : missing value
missing value tells ASOC that this is a GUI property.
To create a GUI double click the .xib (usually MainMenu.xib) file in the project library, if you havenât found this already, to open it in Interface Builder. Objects like text boxes, radio buttons, popups and buttons or even new windows can be dragged from the library window (library and inspector windows can be found in the Tools menu) and properties of these can be edited in the inspector.
To link a variable to a GUI element control click or right click drag from the blue cube in the little window named with [your app name] app delegate to the element and select your chose variable. Please note only properties from the last Xcode save will be listed. These can be referred to as IBOutlets (Interface Builder- IB)
To make buttons or really any clickable object do some action when clicked you must do something similar. In Xcode create a subroutine like normal but add _(sender) at the end, a bit like the terminate one and save. Now create the button(s) (multiple can be assigned to the same action) in Interface Builder, this time drag from the object TO the cube and select the subroutine. When you click a button when running your app it will run the linked subroutine. These can be referred to as IBActions.
Normal subroutines can still be used in the script but donât have underscores.
Craig has great videos and pictures of this process.
Part 1: http://macscripter.net/viewtopic.php?pid=117489#p117489
Part 2: http://macscripter.net/viewtopic.php?pid=117608#p117608
As a little test link
on mysub_(sender)
display dialog "worked"
end mysub_
to a button, build and run and try clicking it.
ASOC commands to get or set values of GUI elements can be triggered with [your variable name]'s [command] or a tell [your variable name] statement, as a personal choice, I mainly use 's. Example:
myTextField's stringValue()
with myTextField linked as an IBOutlet to a Text Field. You could even try replacing âworkedâ with (myTextFieldâs stringValue()) as string. Complete basic example of whatâs been covered so far:
script Testing_2AppDelegate
property parent : class "NSObject"
property myTextField : missing value
on mysub_(sender)
display dialog (myTextField's stringValue()) as string
end mysub_
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return (current application's NSTerminateNow) as integer
end applicationShouldTerminate_
end script
You will often need to unnecessarily coerce values between ASOC and AS. Also donât make the mistake that text fields need to be named myTextField or that it needs to be capitalised -mytextfield.
All Obj-C commands are in the developer documentation in the help menu. To find a command look for the âNSâ name in Interface Builder library window under the the name of the object you want to use in the bottom section, then search it in the Xcode documentation window, then browse for what you want which will be handily be put in categories near the top. Sometimes you may need to view the parent for example stringValue is not in NSTextField but is in the parent NSControl (link at the top).
Obj-C commands listed in the documentation will be in the format of setIntValue: but to use in ASOC these commands must be changed. Replace : with _ and add brackets at the end if there are colons/underscores e.g.
setIntValue: setIntValue_()
insertItemWithTitle:atIndex: insertItemWithTitle_atIndex_()
intValue intValue()
If the command requires parameters it will have a colon (to change to an underscore) for each one, the brackets will contain these parameters e.g. setIntValue_(2) or insertItemWithTitle_atIndex_(âhelloâ,2) these vary and may or may not have a colon and therefore an underscore dependant on whether a parameter is required for example intValue() does not, setIntValue_() does because it needs a number to set something with. Often commands want a sender parameter where you can usually get away with putting in sender if contained in an IBAction subroutine other subroutines will need to be passed what the old IBAction sender was e.g.
on myActionSub_(sender)
otherSub(sender)
end myActionSub_
on otherSub(sender)
windowa's makeKeyAndOrderFront_(sender)
end otherSub
not
on myActionSub_(sender)
otherSub()
end myActionSub_
on otherSub()
windowa's makeKeyAndOrderFront_()
end otherSub
This will not work at all without a parameter, garbage could be used but I prefer to keep things clean.
If you look at commands in the documentation window (continuing example) intValue, setIntValue: (NSControl) and insertItemWithTitle:atIndex: you will notice under the title it has something like:
-
(int)intValue
(int) tells you the kind of value to be returned (this is a getter) -
(void)setIntValue:(int)anInt
(void) tells you it will return nothing (this is a setter) the (int) after the colon (colon is the symbol for required parameter remember) is the kind of parameter required, generally ignore things like anInt after the bracket. -
(void)insertItemWithTitle:(NSString *)title atIndex:(NSInteger)index
Like before no returning value, title parameter must be a string, index parameter must be an integer.
Commonly used commands.
Text box commands:
Text View (NSTextView):
Read- |string|()
|| is used around Obj-C commands which are also in AS because the syntax takes AS as priority. || will not affect anything so donât worry about using them if you are not sure
Write- setString_()
Text Field (NSTextField):
Read- stringValue()
Write- setStringValue_()
Window commands:
open- makeKeyAndOrderFront_()
There are variations as well. One of the sender parameters.
close- performClose_()
(sender too)
One more example this is still basic but more advanced than the last one.
script MultiplierAppDelegate
property parent : class "NSObject"
property number2val : missing value -- Text Field
property number1val : missing value -- Text Field
property resultval : missing value -- Text View
on multiply_(sender) -- button
set oldresult to resultval's |string|() as string
set no1 to number1val's intValue() as integer
set no2 to number2val's intValue() as integer
set newresult to ((no1 * no2) as string) & "
" & oldresult
resultval's setString_(newresult)
end multiply_
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return (current application's NSTerminateNow) as integer
end applicationShouldTerminate_
end script