1

アプリをサンドボックス化できるように、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メソッドが私に与えるのと同じ振る舞いを私に与える解決策を誰かが提案できますか?

4

3 に答える 3

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];
});
于 2013-01-12T14:22:16.280 に答える
1

(上記のomzのコメントに動機付けられて、私はこれを答えとして書いています。)

タスクの完了ハンドラーを使用して、次のタスクの実行を開始できます。

于 2013-01-12T14:44:17.027 に答える
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 /に入れてそのスクリプトを実行すると、すべてが正常に機能するようです。

于 2013-02-11T13:45:18.407 に答える