【问题标题】:Using AppleScript with Apple Events in macOS - Script not working在 macOS 中将 AppleScript 与 Apple 事件一起使用 - 脚本不起作用
【发布时间】:2020-01-04 21:24:38
【问题描述】:

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

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)

        }
    }


【问题讨论】:

  • 避免NSAppleScript——对于任何不平凡的事情来说,它都是一个完整的 PITA。从 ObjC/Swift 访问 AppleScript 的最佳方式是通过 AppleScript-ObjC bridge,它让您可以像调用原生 ObjC 方法一样调用 AppleScript 处理程序。

标签: swift macos applescript macos-carbon appleevents


【解决方案1】:

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

首先,更改脚本,使代码位于处理程序中:

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,让它传递参数并调用我们刚刚定义的处理程序:

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)运行脚本,但是如果你需要传参数,则需要使用这种'handler'方式。

【讨论】:

  • 天啊!这不仅有效,还解决了我们的下一个问题,即如何将数据传递给脚本。真正的主题,收件人等。有趣的是它如何在以下位置插入所有参数:0 ???您在几分钟内解决了 DTS 花了 2 周多的时间才返回不完整的论坛帖子的问题。最后一个问题,我们需要附上一个已经存在于课堂上的 PDF 文档。使用:在最后一段之后使用属性 {file name:theAttachment} 创建新附件。它可以在脚本编辑器中运行,但不会显示在电子邮件中。有任何想法吗?再次感谢您的帮助!
  • 附件不显示的原因只有两个:1. 您在访问文件时遇到了一些安全/权限问题,或者 2. 您发送了错误的路径说明符。脚本编辑器中的邮件附件似乎可以与 posix 路径和别名文件说明符一起使用,因此在处理程序定义中添加第五个参数 (theAttachment),并确保向其发送 text posix 路径(例如, 如果你在 swift 中有 PDF 的 NSURL,请将theUrl.path 作为字符串描述符添加到参数列表中)。
  • 我已经更新了主帖中的示例代码。顺便说一句,“0”索引似乎是“将其添加到列表末尾”的简写。模糊,也许,但不是太神秘......
  • 不想再麻烦你了。但是,附件不起作用。确实找到了一个在脚本编辑器中工作正常但无法让附件在处理程序中工作的脚本。还有一个额外的告诉命令和一个激活。一直在尝试发送和激活的所有组合,但无法使附件正常工作。以下是详细信息stackoverflow.com/questions/57777548/…>感谢您提供任何见解。
  • 不用担心。错误字典中是否有任何内容,还是在script.executeAppleEvent 调用后为零?
猜你喜欢
  • 2022-01-06
  • 1970-01-01
  • 2022-11-02
  • 2021-06-09
  • 1970-01-01
  • 2021-04-24
  • 2018-12-07
  • 1970-01-01
  • 2016-08-21
相关资源
最近更新 更多