问题
I am trying to execute an Automator workflow from a sandboxed AppKit app.
Minimal example + github repo :
NSOpenPanel * panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:NO];
[panel setCanChooseFiles:YES];
[panel setCanChooseDirectories:NO];
[panel setAllowedFileTypes:[NSArray arrayWithObject: @"com.apple.automator-workflow"]];
NSInteger result = [panel runModal];
if (result == NSFileHandlingPanelOKButton) {
NSURL * workflow = [[panel URLs]objectAtIndex:0];
NSLog(@"selected url %@", workflow);
NSError * error = nil;
[AMWorkflow runWorkflowAtURL:workflow withInput:[NSArray arrayWithObject:workflow] error:&error];
if(error) {
NSLog(@"Error while executing workflow %@", [error localizedDescription]);
}
}
From my current understanding of the AMWorkflow API I assume it uses Mach IPC to execute the workflow in a separate Automator Runner process.
This is why I added the following entitlement to my app:
<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
<array>
<string>com.apple.AutomatorRunner</string>
<string>com.apple.Automator</string>
</array>
But apparently Automator Runner tries to connect back to the calling app which fails with the following error msg:
Automator Runner(2717) deny mach-lookup /Users/pbrc/Library/Developer/Xcode/DerivedData/AMWorkflowCaller-arjgkslqihljquelyvybmpsnljrn/Build/Products/Debug/AMWorkf
0 libsystem_kernel.dylib 0x00007fff96ce9686 mach_msg_trap + 10
1 liblaunch.dylib 0x00007fff8db637c4
2 liblaunch.dylib 0x00007fff8db624d9 bootstrap_look_up3 + 69
3 liblaunch.dylib 0x00007fff8db62609 bootstrap_look_up2 + 40
4 Foundation 0x00007fff8f4acffe -[NSMachBootstrapServer portForName:options:] + 102
5 Foundation 0x00007fff8f4b84cb +[NSConnection connectionWithRegisteredName:host:usingNameServer:] + 30
6 Automator Runner 0x0000000100001a51 -[AMRunnerDelegate processArguments] + 487
Any ideas?
回答1:
The simple answer is that the AMWorkflow API does not work in sandboxed applications. There is an alternative API which has been introduced recently, which works with sandboxed applications:
NSUserAutomatorTask executeWithInput:completionHandler:
Using this API you can execute automator scripts that are located in the script folder of your application:
/Users/USERNAME/Library/Application Scripts/BUNDLENAME.APPNAME
There is one significant caveat: Despite the method's "input" argument no input will be passed through to the automator workflow on versions of Mac OS prior to 10.8.3 12D75 (this is/was a bug):
NSUserAutomatorTask * task = [[NSUserAutomatorTask alloc] initWithURL:workflow error:&error];
if(error) {
NSLog(@"Error while creating script task %@", [error localizedDescription]);
}
[task executeWithInput: @"this will never reach your workflow" completionHandler:^(id result, NSError *error){
if(error)
NSLog(@"Error while executing workflow %@", [error localizedDescription]);
}];
来源:https://stackoverflow.com/questions/12149529/using-amworkflow-with-sandboxed-app