I'm trying to script a sandboxed app (which I wrote) from another sandboxed app using ScriptingBridge. I have access groups set up in the target app's sdef, and entitlements configured in the scripting app's sandbox entitlements. However, when I try to send Apple Events to the target (using ScriptingBridge), I see warning: failed to get scripting definition from ~/<snip>/MyApp.app; it may not be scriptable.
logged in the console (the path to the target app is correct).
I've been able to reproduce the problem with a lightly modified version of the Sketch sample code app and a very simple test app that uses scripting bridge. I added <access-group identifier="com.apple.CocoaExamples.Sketch.Draw" access="rw"/>
to many elements in Sketch.sdef, as well as turned on sandboxing for Sketch.
Then, in my test app, I turned on sandboxing with the following entitlements:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.scripting-targets</key>
<dict>
<key>com.apple.CocoaExamples.Sketch</key>
<array>
<string>com.apple.CocoaExamples.Sketch.Draw</string>
</array>
</dict>
</dict>
</plist>
The app does the following:
#import "ViewController.h"
#import "Sketch.h"
@implementation ViewController
- (IBAction)draw:(id)sender {
SketchApplication *sketch = [SBApplication applicationWithBundleIdentifier:@"com.apple.CocoaExamples.Sketch"];
if (![sketch isKindOfClass:[NSClassFromString(@"SketchApplication") class]]) {
NSLog(@"Unable to get SketchApplication for Sketch");
}
}
@end
Upon the call to -applicationWithBundleIdentifier:
, the "warning: failed to get scripting definition" message is logged, and the object returned is an instance of SBApplication
rather than a SketchApplication
.
If I turn off sandboxing in the test app, the error is not logged, and -applicationWithBundleIdentifier:
returns a SketchApplication
as expected. The same is true if I add the com.apple.security.temporary-exception.apple-events
entitlement, though I believe this is unlikely to pass app store review.
Am I missing something beyond defining access groups in the target's sdef and adding the com.apple.security.scripting-targets
entitlement? Does this work for anyone?
I've uploaded the test app and my modified Sketch projects here: https://www.dropbox.com/s/cdml9n5npu8o2m3/SandboxScriptTest.zip?dl=0
I filed a tech support incident with Apple about this, and they confirmed that it is a bug. The only workaround they suggested is to hold onto the (valid) instance of SketchApplication
returned by the first call to -applicationWithBundleIdentifier:
when Sketch is running for later use. This is not really a viable workaround at all in my particular case since the target app is very likely to already be running before the scripting app is launched.
I've filed a radar for this: rdar://27625862.
The other option is to use the com.apple.security.temporary-exception.apple-events
sandbox entitlement. I'll do that for now, and hope that I can justify its use for app store review.