We need to use a AppleScript to create an outgoing email message in macOS. The script works fine in the Script Editor. Using the code recommended by DTS https://forums.developer.apple.com/message/301006#301006 no results, warnings or errors. Same result with sample script from the forum. Need Swift and Apple Events expertise here. Thanks!
import Foundation
import Carbon
class EmailDoc: NSObject {
var script: NSAppleScript = {
let script = NSAppleScript(source: """
set theSubject to "Some Subject"
set theContent to "Some content of the email"
set recipientName to "Some Name"
set recipientAddress to "[email protected]"
tell application "Mail"
# Create an email
set outgoingMessage to make new outgoing message with properties {subject:theSubject, content:theContent, visible:true}
# Set the recipient
tell outgoingMessage
make new to recipient with properties {name:recipientName, address:recipientAddress}
# Send the message
send
end tell
end tell
"""
)!
let success = script.compileAndReturnError(nil)
assert(success)
return script
}()
// Script that is referenced by DTS at https://forums.developer.apple.com/message/301006#301006
// that goes with runScript method below -- runs with no results
/*var script: NSAppleScript = {
let script = NSAppleScript(source: """
on displayMessage(message)
tell application "Finder"
activate
display dialog message buttons {"OK"} default button "OK"
end tell
end displayMessage
"""
)!
let success = script.compileAndReturnError(nil)
assert(success)
return script
}() */
@objc
func runScript() {
let parameters = NSAppleEventDescriptor.list()
parameters.insert(NSAppleEventDescriptor(string: "Hello Cruel World!"), at: 0)
let event = NSAppleEventDescriptor(
eventClass: AEEventClass(kASAppleScriptSuite),
eventID: AEEventID(kASSubroutineEvent),
targetDescriptor: nil,
returnID: AEReturnID(kAutoGenerateReturnID),
transactionID: AETransactionID(kAnyTransactionID)
)
event.setDescriptor(NSAppleEventDescriptor(string: "displayMessage"), forKeyword: AEKeyword(keyASSubroutineName))
event.setDescriptor(parameters, forKeyword: AEKeyword(keyDirectObject))
var error: NSDictionary? = nil
_ = self.script.executeAppleEvent(event, error: &error) as NSAppleEventDescriptor?
print ("runScript",self.script)
}
}
The problem with this code — which is an incredibly un-obvious problem, mind you — is that you're using code meant to run a script handler (a method or subroutine) to try to run the full script. One of the oddnesses of Obj-C's AppleScript classes is that there is no easy way to run a script with parameters, so the workaround is to enclose the code to be executed within a script handler, and use an Apple Event that calls that handler. To make your code work, you'll do something like the following...
First, change the script so that the code is in a handler:
Then alter the Apple Event you construct so that it passes the parameters and calls the handler we just defined:
If you don't need to pass parameters, you could run the script directly using
script.executeAndReturnError(&error), but if you need to pass parameters, you'll need to use this 'handler' approach.