アプリをサンドボックス化できるように、AppleScriptを実行するコードをNSAppleScriptからNSUserAppleScriptTaskに移行しています。私が抱えている問題は、次のように最もよく示されます。
AppleScriptの「test.scpt」は単純です
on run
display dialog "Hello World" buttons {"OK"} default button "OK"
end run
以下のようにNSAppleScriptを使用してこれを10回続けて実行すると、スクリプトは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を使用すると、タスクが同時に実行されているように見えます。前のスクリプトでダイアログが開いていると、次に実行されるスクリプトでエラーが発生するように見えるため、同時実行は「問題」です。これは、次のように示すことができます。
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メソッドが私に与えるのと同じ振る舞いを私に与える解決策を誰かが提案できますか?