简体   繁体   English

在macOS中将AppleScript与Apple Events结合使用-脚本不起作用

[英]Using AppleScript with Apple Events in macOS - Script not working

We need to use a AppleScript to create an outgoing email message in macOS. 我们需要使用AppleScript在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. 使用DTS建议的代码https://forums.developer.apple.com/message/301006#301006没有结果,警告或错误。 Same result with sample script from the forum. 来自论坛的示例脚本的结果相同。 Need Swift and Apple Events expertise here. 这里需要Swift和Apple Events专业知识。 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 "someone@example.com"

            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. Obj-C的AppleScript类的怪异之一是,没有一种简单的方法可以使用参数运行脚本,因此解决方法是将要执行的代码封装在脚本处理程序中,并使用调用该处理程序的Apple Event。 To make your code work, you'll do something like the following... 为了使代码正常工作,您将执行以下操作...

First, change the script so that the code is in a handler: 首先,更改脚本,以使代码位于处理程序中:

var script: NSAppleScript = { 
    let script = NSAppleScript(source: """

    -- This is our handler definition
    on sendMyEmail(theSubject, theContent, recipientName, recipientAddress, attachmentPath)
        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}

                make new attachment with properties {file name:POSIX file attachmentPath}

               -- Mail.app needs a moment to process the attachment, so...
               delay 1

               -- Send the message
               send 
            end tell
        end tell
    end sendMyEmail
    """  
    )!  

Then alter the Apple Event you construct so that it passes the parameters and calls the handler we just defined: 然后更改您构造的Apple Event,以便它传递参数并调用我们刚刚定义的处理程序:

func runScript() {
    let parameters = NSAppleEventDescriptor.list()  
    parameters.insert(NSAppleEventDescriptor(string: "Some Subject"), at: 0)  
    parameters.insert(NSAppleEventDescriptor(string: "Some content of the email"), at: 0)  
    parameters.insert(NSAppleEventDescriptor(string: "Some Name"), at: 0)  
    parameters.insert(NSAppleEventDescriptor(string: "someone@example.com"), at: 0)  
    parameters.insert(NSAppleEventDescriptor(string: attachmentFileURL.path), at: 0)  

    let event = NSAppleEventDescriptor(  
        eventClass: AEEventClass(kASAppleScriptSuite),  
        eventID: AEEventID(kASSubroutineEvent),  
        targetDescriptor: nil,  
        returnID: AEReturnID(kAutoGenerateReturnID),  
        transactionID: AETransactionID(kAnyTransactionID)  
    )  

    // this line sets the name of the target handler
    event.setDescriptor(NSAppleEventDescriptor(string: "sendMyEmail"), forKeyword: AEKeyword(keyASSubroutineName))

    // this line adds the parameter list we constructed above  
    event.setDescriptor(parameters, forKeyword: AEKeyword(keyDirectObject))  

    var error: NSDictionary? = nil  
    _ = self.script.executeAppleEvent(event, error: &error) as NSAppleEventDescriptor?  

    print ("runScript",self.script)

    }
}

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. 如果不需要传递参数,则可以使用script.executeAndReturnError(&error)直接运行脚本,但是如果需要传递参数,则需要使用这种“处理程序”方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM