Simple example showing different syntax in ASObjC. This example use AVFoundation to play a mp3 song from URL on internet. As you could see its use tell block with properties from AVAudioPlayer class. But we could also do the same part in different way. The second script show that. And we could also do it without setValue:forKey and valueForKey: The third script show that. You could also see that we add set with capital letter for the first character and end and before its value a colon.
And with a Boolean value we add () at the end. The syntax is kind of flexible in ASObjC and some approaches are more Objective-C look a like when others it more AppleScript.
use framework "Foundation"
use framework "AVFoundation"
use scripting additions
set theString to "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
set theURL to current application's |NSURL|'s URLWithString:theString
set theData to current application's NSData's dataWithContentsOfURL:theURL
set {audioPlayer, theError} to current application's AVAudioPlayer's alloc()'s initWithData:theData |error|:(reference)
if audioPlayer is missing value then error (theError's localizedDescription() as text)
tell audioPlayer
-- The number of times the audio repeats playback.
numberOfLoops to 0
-- The audio player’s volume relative to other audio output.
volume to 1.0
-- Prepares the player for audio playback.
prepareToPlay()
-- Plays audio asynchronously.
play()
end tell
if (audioPlayer's playing) as boolean is true then
display dialog "Audio is playing..." buttons {"OK"} default button "OK"
end if
if (result's button returned) is "OK" then return audioPlayer's |stop|()
Script ex2
audioPlayer's setValue:0 forKey:"numberOfLoops"
audioPlayer's setValue:1.0 forKey:"volume"
audioPlayer's valueForKey:"prepareToPlay"
audioPlayer's valueForKey:"play"
Script ex3
audioPlayer's setNumberOfLoops:0
audioPlayer's setVolume:1.0
audioPlayer's prepareToPlay()
audioPlayer's play()
Here is simple example in Xcode to use play button and stop button with textfield as input URL
I’m not 100% if I need the use statement it was working without it.
You need to create play & stop button and textfield in Interface Builder and delegate → textField
and buttons → delegate and that’s it.
In Xcode handlers look like
on propertyName_(params)
– some code
end propertyName_
-- use framework "Foundation"
-- use framework "AVFoundation"
-- use scripting additions
script AppDelegate
property parent : class "NSObject"
property urlString : missing value
property audioPlayer : missing value
-- IBOutlets
property theWindow : missing value
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
end applicationShouldTerminate_
on buttonPlay_(sender)
set theString to urlString's stringValue()
set theURL to current application's |NSURL|'s URLWithString:theString
set theData to current application's NSData's dataWithContentsOfURL:theURL
set {audioPlayer, theError} to current application's AVAudioPlayer's alloc()'s initWithData:theData |error|:(reference)
if audioPlayer is missing value then error (theError's localizedDescription() as text)
audioPlayer's setValue:0 forKey:"numberOfLoops"
audioPlayer's setValue:1.0 forKey:"volume"
audioPlayer's valueForKey:"prepareToPlay"
audioPlayer's valueForKey:"play"
end buttonPlay_
on buttonStop_(sender)
tell audioPlayer to |stop|()
end buttonStop_
end script
Here we hardcode it and by using handlers its 10 minutes extra time compare to Xcode version.
So not only is Xcode Interface Builder useful it make the process faster.
use framework "Foundation"
use framework "AppKit"
use scripting additions
property arguments : missing value
property audioPlayer : missing value
property textFieldWithURLString : missing value
on run
if current application's NSThread's isMainThread() as boolean then
my performDialog:arguments
else
my performSelectorOnMainThread:"performDialog:" withObject:arguments waitUntilDone:true
end if
end run
on performDialog:arguments
set buttonPlay to createButtonWithTitle("Play", 490, 75, 64, 21, "buttonPlay:")
set buttonStop to createButtonWithTitle("Stop", 490, 50, 64, 21, "buttonStop:")
set textFieldWithURLString to createTextfieldWithPlaceholder("Type the url to play", 20, 50, 462, 21)
set subviewItems to {buttonPlay, buttonStop, textFieldWithURLString}
set {theWidth, theHeight} to {564, 114}
set theWindow to createWindowWithRect(subviewItems, 0, 0, theWidth, theHeight)
theWindow's setTitle:"Examples with AVAudioPlayer..."
theWindow's |center|()
theWindow's makeKeyAndOrderFront:me
end performDialog:
on buttonPlay:sender
set theString to textFieldWithURLString's stringValue()
set theURL to current application's |NSURL|'s URLWithString:theString
set theData to current application's NSData's dataWithContentsOfURL:theURL
set {audioPlayer, theError} to current application's AVAudioPlayer's alloc()'s initWithData:theData |error|:(reference)
if audioPlayer is missing value then error (theError's localizedDescription() as text)
audioPlayer's setValue:0 forKey:"numberOfLoops"
audioPlayer's setValue:1.0 forKey:"volume"
audioPlayer's valueForKey:"prepareToPlay"
audioPlayer's valueForKey:"play"
end buttonPlay:
on buttonStop:sender
tell audioPlayer to |stop|()
end buttonStop:
on createButtonWithTitle(title, x, y, width, height, selector)
set theButtonTitle to current application's NSButton's buttonWithTitle:title target:me action:selector
theButtonTitle's setFrameSize:{width, height}
theButtonTitle's setFrameOrigin:{x, y}
return theButtonTitle
end createButtonWithTitle
on createTextfieldWithPlaceholder(placeholder, x, y, width, height)
set textFieldSSize to current application's NSMakeRect(x, y, width, height)
set theTextField to current application's NSTextField's alloc()'s initWithFrame:textFieldSSize
theTextField's setPlaceholderString:placeholder
return theTextField
end createTextfieldWithPlaceholder
on createWindowWithRect(subviewItems, x, y, width, height)
set windowSize to current application's NSMakeRect(x, y, width, height)
set winStyle to (current application's NSWindowStyleMaskTitled as integer) + (current application's NSWindowStyleMaskClosable as integer)
set theWindow to current application's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:2 defer:true
repeat with anSubview in subviewItems
(theWindow's contentView()'s addSubview:anSubview)
end repeat
return theWindow
end createWindowWithRect