在macOS中将AppleScript与Apple Events结合使用-脚本不起作用 [英] Using AppleScript with Apple Events in macOS - Script not working

查看:325
本文介绍了在macOS中将AppleScript与Apple Events结合使用-脚本不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们需要使用AppleScript在macOS中创建外发电子邮件.该脚本在脚本编辑器中可以正常工作.使用DTS推荐的代码 https://forums.developer.apple.com/message/301006#301006 没有结果,警告或错误.与来自论坛的示例脚本相同的结果.这里需要Swift和Apple Events专业知识.谢谢!

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 "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)

        }
    }


推荐答案

此代码的问题-请注意,这是一个非常明显的问题,即您正在使用用于运行脚本的代码处理程序(一种方法或子例程)来尝试运行完整脚本. Obj-C的AppleScript类的怪异之一是,没有一种简单的方法可以运行带有参数的脚本,因此解决方法是将要执行的代码封装在脚本处理程序中,并使用一个调用该处理程序的Apple Event.为了使代码正常工作,您将执行以下操作...

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:

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
    """  
    )!  

然后更改您构造的Apple Event,以便它传递参数并调用我们刚刚定义的处理程序:

Then alter the Apple Event you construct so that it passes the parameters and calls the handler we just defined:

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)

    }
}

如果不需要传递参数,则可以直接使用script.executeAndReturnError(&error)运行脚本,但是如果需要传递参数,则需要使用这种处理程序"方法.

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.

这篇关于在macOS中将AppleScript与Apple Events结合使用-脚本不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆