你可以从Swift应用程序执行Applescript脚本吗?

时间:2014-08-06 14:45:20

标签: swift applescript

我有一个发送电子邮件的简单AppleScript。如何在Swift应用程序中调用它?

(我无法通过Google找到答案。)

6 个答案:

答案 0 :(得分:53)

作为Kamaros suggests,您可以直接致电NSApplescript,而无需通过NSTask启动单独的流程(CRGreen suggests。)

Swift Code

let myAppleScript = "..."
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: myAppleScript) {
    if let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(
                                                                       &error) {
        print(output.stringValue)
    } else if (error != nil) {
        print("error: \(error)")
    }
}

答案 1 :(得分:23)

未经测试,但看起来可以做类似的事情(添加任意脚本路径):

import Foundation

let task = NSTask()
task.launchPath = "/usr/bin/osascript"
task.arguments = ["~/Desktop/testscript.scpt"]

task.launch()

答案 2 :(得分:3)

对于从<{3}}

创建NSAppleEventDescriptor时获取 Swift 4 以下警告的任何人
  

检查选项中使用的'NSAppleEventDescriptor'类型的非可选表达式

您可以使用此编辑的简短版本删除它:

let myAppleScript = "..."
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: myAppleScript) {
    if let outputString = scriptObject.executeAndReturnError(&error).stringValue {
        print(outputString)
    } else if (error != nil) {
        print("error: ", error!)
    }
}

然而,您可能也意识到了;使用此方法,每次运行脚本时,系统都会将此消息记录到控制台:

  

AppleEvents:收到的mach msg不是预期的复杂类型   在getMemoryReference中。

显然,这是苹果员工开发人员声明的错误,并且被称为“只是”无害的日志垃圾邮件,并且计划在未来的操作系统中删除更新,正如您在下面这个非常长的zekel's answer和SO问题中看到的那样:

apple developer forum post

感谢Apple,因为那些垃圾控制台日志被抛出。

答案 3 :(得分:2)

您可以尝试使用Apple的技术说明TN2084中的NSAppleScript 在Cocoa应用程序中使用AppleScript脚本 https://developer.apple.com/library/mac/technotes/tn2084/_index.html

NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
            @"\
            set app_path to path to me\n\
            tell application \"System Events\"\n\
            if \"AddLoginItem\" is not in (name of every login item) then\n\
            make login item at end with properties {hidden:false, path:app_path}\n\
            end if\n\
            end tell"];

returnDescriptor = [scriptObject executeAndReturnError: &errorDict];

答案 4 :(得分:2)

截至2018年3月,我认为这个帖子最强的答案仍然是accepted answer from 2011。涉及使用NSAppleScript或OSAScript的实现遇到了一些缺点,即存在一些轻微但非常令人不愉快的内存泄漏,而没有真正提供任何额外的好处。任何努力获得正确执行答案的人(在Swift 4中)都可能想尝试这个:

let manager = FileManager()
// Note that this assumes your .scpt file is located somewhere in the Documents directory
let script: URL? = try? manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
if let scriptPath = script?.appendingPathComponent("/path/to/scriptName").appendingPathExtension("scpt").path {
    let process = Process()
    if process.isRunning == false {
        let pipe = Pipe()
        process.launchPath = "/usr/bin/osascript"
        process.arguments = [scriptPath]
        process.standardError = pipe
        process.launch()
    }
}

答案 5 :(得分:1)

我挣扎了几个小时,但没有任何效果。最后我设法通过shell运行AppleScript:

let proc = Process()
proc.launchPath = "/usr/bin/env"
proc.arguments = ["/usr/bin/osascript", "scriptPath"]
proc.launch()

Dunno这是最好的方法,但至少它可行。