如何排队NSUserAppleScriptTask执行?

时间:2013-01-12 14:04:03

标签: objective-c applescript

我正在将一些从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方法相同的行为吗?

3 个答案:

答案 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 /并执行该脚本一切正常