Асинхронно выполнять сценарий оболочки в Cocoa-Applescript?

Я новичок в Cocoa и AppleScript. Недавно я хочу сделать что-то с помощью команды «do shell script» в Cocoa-AppleScript много раз и одновременно показать окно с индикатором выполнения, чтобы указать, сколько раз я это сделал.

Мой код выглядит так:

property progressBar: missing value
on applicationWillFinishLaunching_(aNotification)
    repeat with i from 1 to 8
        set progressBar's doublevalue to i
        do shell script "sleep 1"
        delay 1
    end repeat
end applicationWillFinishLaunching_

Это покажет индикатор выполнения и указывает прогресс. Однако окно, содержащее индикатор выполнения, будет неактивным, пока повторение не будет завершено. Я думаю, это связано с тем, что приложение Cocoa-AppleScript имеет только один поток, поэтому, когда оно выполняет команду «сделать сценарий оболочки», графический интерфейс просто не может обрабатывать другие события. Я попытался запустить сценарий оболочки в фоновом режиме с хвостовым «&», но он ведет себя как зависший и по-прежнему занимает много времени.

Я думаю, что даже команду «сделать сценарий оболочки» можно выполнить в фоновом режиме. Мне все равно нужно получать уведомления, когда она будет завершена, чтобы обновить индикатор выполнения, но я не знаю, как этого добиться.

Итак, мой вопрос: как сделать что-то с помощью «выполнить сценарий оболочки» асинхронно и получить информацию, когда задание будет завершено, в Cocoa-AppleScript?

(Кстати, если я удалю эту строку «задержка 1», индикатор выполнения даже не обновится, кто-нибудь знает причину?)


person Ping Fang Chiang    schedule 20.04.2016    source источник
comment
Вы правы насчет проблемы с одним потоком, которая может быть проблемой при попытке сделать что-то подобное с помощью Applescript. Существуют приложения-оболочки (одно из них называется Platypus), которые могут делать то, что вы хотите, так что, возможно, рассмотреть это как вариант.   -  person l'L'l    schedule 20.04.2016
comment
@l'L'l Я попробую использовать это приложение. Спасибо!   -  person Ping Fang Chiang    schedule 20.04.2016


Ответы (1)


Используйте 1_. Вам нужно будет использовать несколько строк ObjC, чтобы определить обработчик завершения, который обращается к вашему коду AS, поскольку ASOC не поддерживает блоки сам по себе, но в остальном он делает именно то, что вам нужно.

person foo    schedule 20.04.2016
comment
На самом деле причина, по которой я решил использовать AppleScript для этого, заключается в том, что я вообще не хочу изучать ObjC... Тем не менее, спасибо за помощь. :) - person Ping Fang Chiang; 20.04.2016
comment
Если вы хотите запустить подпроцесс асинхронно и получить уведомление о завершении, используйте NSTask. Да, отсутствие поддержки блоков в ASOC классно раздражает, но это не непреодолимо. Причина, по которой использование do shell script с & не возвращает результат немедленно, заключается в том, что каналы stdout и stderr подпроцесса все еще подключены к вашему процессу; однако, если вы перенаправите их, ваш процесс больше не будет получать никакой обратной связи. Без сомнения, есть сумасшедшие способы, которыми вы можете это сделать, но вы просто связываете себя узлами и потенциально создаете всевозможные неприятные ловушки. Проще всего использовать ObjC. - person foo; 20.04.2016
comment
Или, предполагая, что вы не пишете никаких сценариев приложений, что AppleScript делает правильно, вы можете просто полностью забыть об использовании AppleScript, смириться с этим и вместо этого изучать Swift. По крайней мере, со Swift вы получите большое, знающее сообщество пользователей, обширную поддержку инструментов и документации, а также хорошо поддерживаемый язык, который не безнадежно умирает, даже если эта чертова штука тупо усложняется и все еще глючит, как муравейник. Но эх, это Будущее. - person foo; 20.04.2016
comment
Я изучил Swift некоторое время. Хоть он и глючит, раздражает некоторыми фичами, а также своей убогой IDE (xcode), для меня он все же намного понятнее, чем ObjC. Это еще одна причина, по которой я не хочу тратить время на изучение ObjC. Но этот проект, который я пишу, должен поддерживать версию ОС для OS X 10.7, на которой Swift недоступен. Так появился этот вопрос AppleScript... - person Ping Fang Chiang; 21.04.2016