Setting NSUserAutomatorTask variables without requiring Automator Workflows to declare that variable

安稳与你 提交于 2019-12-01 17:00:29

问题


I'm using NSUserAutomatorTask to launch a .workflow file, created via the Automator app in macOS 10.13.

I'm passing variables to the workflow via the variables property:

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

The parent app is sandboxed. The script is located in the .applicationScriptsDirectory and runs successfully when variables are not set, or when the same variables are set from the app and declared in the workflow.

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

The workflow fails to run with the error:

No variable named "randomVariable"

However, if I edit the workflow and add a Variable to match the one set in code, everything is fine.

I no longer get the error, and the workflow executes correctly:

This is an issue because I want to pass multiple pieces of information as variables to any potential workflow, and for each workflow to individually decide to handle each needed parameter.

I do not want to require that every workflow declare the variables that my app will optionally provide.

Note that in my sample workflow the variable is never used. I do not want the additional requirement that it be declared.

Is there any way to avoid each workflow declaring the variables that my app passes when executing the workflow?

Or, is there a way to inspect which variables a workflow has declared? I could then only pass the ones actually used by the workflow.


回答1:


The AMWorkFlow methods setValue(_:forVariableWithName:) and valueForVariable(withName:) both safely determine if that variable is set in the workflow file.

So, construct an AMWorkFlow alongside your NSUserAutomatorTask. Only set the variables that the script is using, as indicated by the AMWorkFlow:

if let automatorTask = try? NSUserAutomatorTask(url: url) {
    if let varChecker = try? AMWorkflow(contentsOf: url) {
        automatorTask.variables = POSSIBLE_VARIABLES.filter {
            return varChecker.setValue($0.value, forVariableWithName: $0.key)
            // -or- //
            return varChecker.valueForVariable(withName: $0.key) != nil
        }
    }

    automatorTask.execute(withInput: nil, completionHandler: nil)
}

AMWorkFlow does not execute at all in the Sandbox, so you must use NSUserAutomatorTask to actually run the workflow.

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.}



来源:https://stackoverflow.com/questions/52507620/setting-nsuserautomatortask-variables-without-requiring-automator-workflows-to-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!