我正在将一些从NSAppleScript执行AppleScripts的代码迁移到NSUserAppleScriptTask,以便我可以对我的应用程序进行沙盒处理。我遇到的问题可以最好地证明如下:
AppleScript" test.scpt"简直就是
on run
display dialog "Hello World" buttons {"OK"} default button "OK"
end run
如果我连续10次使用NSAppleScript执行此操作,则脚本执行10次,每次执行都等待上一次执行完成。
NSURL *script = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"scpt"]];
for (int i=0; i<10; i++) {
NSDictionary *error = nil;
NSAppleScript *task = [[NSAppleScript alloc] initWithContentsOfURL:script error:nil];
[task executeAndReturnError:&error];
if (error!=nil) {
NSLog(@"AppleScript error: %@", error);
}
[task release];
}
然而,使用NSUserAppleScriptTask看起来任务是同时执行的。并发执行是一个问题&#34;因为看起来如果前一个脚本打开了一个对话框,那么下一个要执行的脚本就会出错。这可以证明如下:
NSURL *script = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"scpt"]];
for (int i=0; i<10; i++) {
NSError *error;
NSUserAppleScriptTask *task = [[NSUserAppleScriptTask alloc] initWithURL:script error:&error];
[task executeWithCompletionHandler:^(NSError *error) {
if (error){
NSLog(@"Script execution failed with error: %@", [error localizedDescription]);
}
}];
[task release];
}
这会导致10次执行中的9次出现以下错误:
execution error: "Hello World" doesn’t understand the «event sysodlog» message. (-1708)
我认为正确的解决方案是使用gcd或NSOperationQueue对每个操作进行排队,但我还没有设法构建一个等待NSUserAppleScriptTask的完成块在开始下一个任务之前执行的队列。
任何人都可以提出一个解决方案,它会给我与NSAppleScript方法相同的行为吗?
答案 0 :(得分:2)
您可以从调度队列(或操作队列)运行脚本,并使用NSConditionLock
等待每个脚本完成。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:0];
NSURL *script = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"scpt"]];
for (int i=0; i<10; i++) {
NSError *error;
NSUserAppleScriptTask *task = [[NSUserAppleScriptTask alloc] initWithURL:script error:&error];
[task executeWithCompletionHandler:^(NSError *error) {
if (error){
NSLog(@"Script execution failed with error: %@", [error localizedDescription]);
}
[lock lock];
[lock unlockWithCondition:1];
}];
[task release];
//This will wait until the completion handler of the script task has run:
[lock lockWhenCondition:1];
[lock unlockWithCondition:0];
}
[lock release];
});
答案 1 :(得分:1)
(由omz上面的评论激发我写这个作为答案。)
您可以使用任务的完成处理程序来开始执行下一个任务。
答案 2 :(得分:0)
你是如何通过沙盒的? 无论我尝试什么,我都会得到类似的东西:
Script execution error: The file “create.scpt” couldn’t be opened because you don’t have permission to view it.
当启用沙盒或手动执行脚本时,一切正常
享:
com.apple.security.temporary-exception.apple-events
com.apple.systemevents
com.apple.applescript
TY。
编辑: 似乎如果我将脚本放入〜/ Library / Application Scripts / com.myapp /并执行该脚本一切正常