Статьи

JavaScript для автоматизации OS X на примере

Автор  Майкл Крамп 

Apple очень близка к выпуску новой операционной системы под названием Yosemite. Все говорили об iOS 8, iPhone 6, iPhone 6 Plus и часах, но одной важной особенностью был  JavaScript для OS X Automation . Несмотря на то, что это, возможно, было упущено журналистами, оно не было пропущено  Телериком . Берк Холланд создал  отличный пост, в  котором рассказывалось о том, что JavaScript теперь является первоклассным гражданином. В этом посте я собираюсь показать вам, как вы можете использовать JavaScript для OS X Automation, поскольку на нем почти нет никакой информации, кроме  предварительной документации на сайте Apple.

Примечание. Я использую API, все еще находящиеся в разработке. Все, что показано ниже, может быть изменено.

Начиная

После того, как вы установили Yosemite, перейдите в «Приложения» -> «Утилиты» и переходите вниз, пока не увидите Редактор сценариев, как показано на  рисунке 1.

Рисунок 1: Редактор скриптов.

Рисунок 1  : Редактор скриптов.

Раньше единственным вариантом для создания автоматизированных задач был AppleScript, теперь вы увидите, что JavaScript был добавлен.

javascriptoption

Выберите JavaScript и давайте что-нибудь построим.

Пример: автоматизация сообщения электронной почты

Если в прошлом у вас были автоматизированные задачи, то вы наверняка взаимодействовали с приложением Mail. Ниже приведен фрагмент, написанный на  AppleScript .

tell application "Mail"
    set theMessage to make new outgoing message with properties 
     {visible:true, subject:"Thanks for buying from us!", content:"My Body"}   
end tell

Я взял тот же фрагмент и добавил немного более сложный контент, но написал его целиком, используя  JavaScript .

Mail = Application('Mail');

content = "Hi Michael,\n\n"
      + "Hello, How are you! \n\nThanks for stopping by today!"
      + " We really appreciate your business \n\n"
      + "Sincerely,\n\n"
      + "Company Name";

msg = Mail.OutgoingMessage({
    subject: "Thanks for buying from us!",
    content: content,
    visible: true
});

Mail.outgoingMessages.push(msg);

Mail.activate();

Несколько вещей, чтобы отметить здесь:

  • Точки с запятой необязательны из-за  автоматической вставки точек с запятой (ASI) .
  • Я создал переменную в глобальной области видимости; вместо использования, например:
    var Mail = Application (‘Mail);
  • Я могу использовать одинарные или двойные кавычки для жестко закодированных значений.

Если этот скрипт запущен, то появится следующее диалоговое окно электронной почты, как показано на  рисунке 2

Рисунок 2: Сообщение электронной почты с заполненными полями.

Рисунок 2  : Сообщение электронной почты с заполненными полями.

Но как вы узнаете, какие свойства доступны?

Хороший вопрос, если вы находитесь в Script Editor, то вы можете нажать «Окно» -> «Библиотека», чтобы увидеть список доступных приложений, с которыми вы можете взаимодействовать. Если мы выберем почтовое приложение, оно по умолчанию будет AppleScript, просто измените его на JavaScript, и вы увидите свойства, доступные в  OutgoingMessage классе, который мы только что использовали на рисунке 3 .

Рисунок 3: Изучение класса OutgoingMessage из Документации.

Рисунок 3  : Изучение  OutgoingMessage класса из Документации.

Это круто, но как насчет других приложений?

Приложение Notes — это еще одно приложение, с которым мы можем взаимодействовать, но Apple ввела меры безопасности, чтобы предотвратить появление вредоносных сценариев. Мы можем взаимодействовать с приложением Notes всего несколькими строками JavaScript.

Notes = Application('Notes');
Notes.activate();

delay(1);
SystemEvents = Application('System Events');
Notes = SystemEvents.processes['Notes'];

Notes.windows[0].splitterGroups[0].groups[1].groups[0].buttons[0].click();

Если вы запустите это приложение, вы увидите следующее диалоговое окно, показанное на  рисунке 5 .

Рисунок 5: Диалог безопасности и конфиденциальности.

Рисунок 5  : Диалог безопасности и конфиденциальности.

Если вы нажмете «Открыть системные настройки», вы сможете предоставить этому сценарию доступ, и приложение Notes откроется автоматически.

Я уверен, что теперь вы задаетесь вопросом, как запустить эти сценарии, не находясь внутри   приложения Script Editor . Вы можете сделать это, нажав «Файл» -> «Экспорт», затем измените формат на «Приложение», как показано на  рисунке 6 .

Рисунок 6: Из скрипта в приложение!

Рисунок 6  : Из скрипта в приложение!

Другие задачи автоматизации

Возможно, вы не хотите взаимодействовать с приложением, может быть, вы хотите, чтобы ваше приложение говорило с пользователем. Вы можете сделать это с помощью нескольких строк JavaScript

App = Application.currentApplication();
App.includeStandardAdditions = true;
App.say("Hello from Telerik Headquarters");

При этом будут использоваться голос и язык по умолчанию, установленные в вашей системе, для произнесения слов «Привет из Telerik Headquarters».

Вы также можете использовать его для захвата ввода, например, имени:

App = Application.currentApplication();

App.includeStandardAdditions = true;

answer = App.displayDialog('Please enter your Name', {
  withTitle: 'Name',
  defaultAnswer: 'Telerik'
});

Появится подсказка ( рисунок 7 ), и вы увидите в окне результатов, что они на самом деле набрали ( рисунок 8 ). В этом случае я набрал свое имя «Майкл».

Рисунок 7: Диалоговое сообщение от JavaScript Automation

Рисунок 7  : Диалоговое сообщение от JavaScript Automation

Рисунок 8: Окно результатов

Рисунок 8  : Окно результатов

Доступ к JavaScript Automation также можно получить через терминал

Surprisingly enough, JavaScript Automation can also be helpful for those that use bash to automate tasks. Here is an example command line that opens Safari and a new tab and navigates to http://www.telerik.com by usingosascript interactive mode. The rest is plain JavaScript that we talked about before.

osascript -l JavaScript -i
Safari = Application("Safari");
window = Safari.windows[0];
window.name();
tab = Safari.Tab({url:"http://www.telerik.com"});
window.tabs.push(tab); 
window.currentTab = tab;

The below screenshot shows what it looks like in the terminal window in Figure 9

Safari will open and generate a new tab as shown below:

браузер

Look back through the terminal window and notice that when I called window.name() it returned “Top Sites”. This could be useful for understanding what page a user is on.

There’s an Objective-C Bridge to Advantage Of

This is useful if you wish to use frameworks not present in the Foundation framework used by default. You can take advantage of frameworks like Cocoa by implementing the following code.

ObjC.import('Cocoa');
str = $.NSString.alloc.initWithUTF8String('Writing text to file through obj-c bridge.');
str.writeToFileAtomically('/Users/MichaelCrump/FromObjCBridge.txt', true);

This code imports the Cocoa Framework, initializes an NSString with text and calls thewriteToFileAtomically method passing in the file location and setting the second pararameter to true. This will ensure that the old file will not be changed or removed until the new version is completely on the disk.

We can navigate to our folder and open the text file and see the expected results in Figure 10

Рисунок 10: Мост Obj-C, запись файла на диск

Figure 10 : Obj-C Bridge Writing a File to Disk

Even more Opportunities for JavaScript Developers

We are learning more and more about the implications of JavaScript becoming a first-class citizen in Yosemite. It is also front and center for NativeScript. NativeScript enables developers to use JavaScript to build native apps leveraging readily available or custom device APIs, such as those for camera, accelerometer, geolocation and more. There is a lot to talk about with NativeScript, but I’ll point you to the FAQ if you want to learn more.

NativeScript allows you to build native applications for iOS, Android and Windows Universal using JavaScript.

Bright Future Ahead

I’m very excited about what I’ve seen so far with JavaScript for OS X Automation. Prior to writing this article, I’d never used AppleScript before, but had written JavaScript. I was able to use the syntax familiar to me and successfully write automation tasks. JavaScript developers all over the world should rejoice even if they don’t plan on writing automation tasks because it shows that skillset is becoming more and more important.