设置 NSUserAutomatorTask 变量而不需要 Automator Workflows 声明该变量

Setting NSUserAutomatorTask variables without requiring Automator Workflows to declare that variable

我正在使用 NSUserAutomatorTask 启动 .workflow 文件,该文件是通过 macOS 10.13 中的 Automator 应用程序创建的。

我正在通过 variables 属性:

将变量传递给工作流

https://developer.apple.com/documentation/foundation/nsuserautomatortask/1418099-variables

父应用已被沙盒化。当未设置变量时,或者当从应用程序设置相同变量并在​​工作流中声明时,脚本成功位于 .applicationScriptsDirectory 和 运行 中。

if let workflow = try? NSUserAutomatorTask(url: url) {

    workflow.variables = ["randomVariable": "value"] // NOTE

    workflow.execute(withInput: nil) { (value, error) in
        if let error = error {
            print(error) // No variable named "randomVariable"
        }
    }
}

工作流无法 运行,错误为:

No variable named "randomVariable"

但是,如果我编辑工作流程并添加一个变量来匹配代码中的设置,一切都很好。

我不再收到错误,工作流正确执行:

这是一个问题,因为我想将多条信息作为变量传递给任何潜在的工作流,并让每个工作流单独决定处理每个需要的参数。

我不想要求每个工作流声明我的应用程序将可选提供的变量。

请注意,在我的示例工作流程中从未使用过该变量。我不希望声明它的附加要求。

有什么方法可以避免每个工作流声明我的应用程序在执行工作流时传递的变量?

或者,有没有办法检查工作流声明了哪些变量?然后我只能传递工作流实际使用的那些。

AMWorkFlow 方法 setValue(_:forVariableWithName:)valueForVariable(withName:) 都可以安全地确定是否在工作流文件中设置了该变量。

因此,在您的 NSUserAutomatorTask 旁边构建一个 AMWorkFlow。仅设置脚本正在使用的变量,如 AMWorkFlow:

所示
if let automatorTask = try? NSUserAutomatorTask(url: url) {
    if let varChecker = try? AMWorkflow(contentsOf: url) {
        automatorTask.variables = POSSIBLE_VARIABLES.filter {
            return varChecker.setValue([=10=].value, forVariableWithName: [=10=].key)
            // -or- //
            return varChecker.valueForVariable(withName: [=10=].key) != nil
        }
    }
        
    automatorTask.execute(withInput: nil, completionHandler: nil)
}

AMWorkFlow 根本不会在沙盒中执行,因此您必须使用 NSUserAutomatorTask 才能真正 运行 工作流程。

do {
    try AMWorkflow.run(at: url, withInput: nil)
} catch let error {
    print(error)
}

Automator encountered an error running this workflow:

Sandboxed applications can not use Automator.framework to run workflows.

Error Domain=com.apple.Automator Code=0 "Automator encountered an error running this workflow: “Sandboxed applications can not use Automator.framework to run workflows.”" UserInfo={NSUnderlyingError=0x604000e498a0 {Error Domain=com.apple.Automator Code=0 "Sandboxed applications can not use Automator.framework to run workflows." UserInfo={NSLocalizedDescription=Sandboxed applications can not use Automator.framework to run workflows.}}, NSLocalizedDescription=Automator encountered an error running this workflow: “Sandboxed applications can not use Automator.framework to run workflows.”, NSLocalizedFailureReason=Sandboxed applications can not use Automator.framework to run workflows.}