jxa快速入門,Javascript已加入AppleScript全家桶


因為工作環境基本是以跨平台為主,所以純mac本地化的AppleScript一直關注是不夠的,前幾天找資料發現AppleScript也在迅速的進步着,目前已經對Javascript做了比較好的支持------當然早就支持,現在只是感覺上更好了。這項技術的全稱是JavaScript for Automation,算一項比較新的技術,簡稱JXA。
本博不是學術研究性的,因此完全從實用出發,力求給出自己的實用性見解而不是長篇大論引用官方文字。這里給出我總結的幾個特點:

  • 脫離腳本編輯器Script Editor運行更順暢,支持也更好,不再出現原來的一些莫名其妙問題。
  • 支持Object C對象的嵌入,並以其為橋梁調用c的函數。
  • 支持腳本庫,除了自己寫腳本庫,還可以使用node.js的腳本。
  • 運行的速度很快,對mac下的各個應用支持良好,定制起來很順手。

先介紹幾個資源:
OSX ReleaseNotes:https://developer.apple.com/library/content/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/Articles/Introduction.html
AppleScript的官方參考手冊:https://developer.apple.com/library/content/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html#//apple_ref/doc/uid/TP40000983-CH208-SW1
寫的很詳細的一本入門手冊:https://github.com/JXA-Cookbook/JXA-Cookbook/wiki/Foreword,本文很多樣例代碼來自於此。

使用方法,我們這里拋棄mac內置的腳本編輯器,如同我們熟悉的其它類型js腳本一樣來使用。首先介紹適合初學者練習用的命令行交互式運行環境,也叫REPL (read-eval-print-loop):

osascript -il JavaScript

在交互環境中,首先獲取當前運行的app,然后運行附加腳本執行,幾乎所有的腳本都先要執行這兩句來獲取腳本運行的環境:

>> var app = Application.currentApplication()			//這是獲取當前運行的app
=> undefined		//交互環境的返回值,這里先不用管
>> app.includeStandardAdditions = true		//打開允許運行腳本
=> true

然后比如我們彈出一個警告框:

app.displayAlert('wow', { message: 'I like JavaScript' })

回車后會立即執行,你可以看到mac屏幕上彈出的gui對話框。
接下來,如果連在一起,成為一個腳本文件,應當是這個樣子:

#!/usr/bin/env osascript -l JavaScript

var app = Application.currentApplication()
app.includeStandardAdditions = true
app.displayAlert('wow', { message: 'I like JavaScript' });

把上面的代碼保存為一個文件,比如叫testAlert.js,第一句可能是唯一需要解釋的,#!開頭表示是腳本標志,后面的是腳本解釋器的路徑,在這里是/usr/bin/env osascript -l JavaScript,/usr/bin/env的意思是在環境參量中尋找后面的osascript命令來執行,再后面則是執行參數。
保存為文本文件之后,chmod +x testAlert.js,隨后./testAlert.js就可以執行了。效果跟交互式環境運行是相同的。

通過Objc調用c語言庫函數的例子:

#!/usr/bin/env osascript -l JavaScript
//引用c的函數庫
ObjC.import('stdlib')
//這樣引用的函數,都在$.這個域下面
function run(argv) {    //似乎相當於main函數,是自動啟動的
  argc = argv.length // If you want to iterate through each arg.

  status = $.system(argv.join(" "))        //相當於c的system(...)
    //這里實際是把所有的參數當做參數來執行一個system調用
  $.exit(status >> 8)	//使用c函數exit來退出程序並給出返回值
}

引用函數庫,默認情況下,系統可以從三個位置搜索函數庫:

  • ~/Library/Script Libraries/
  • 一個macos app包的Contents/Library/Script Libraries/路徑。(這個從OSX10.11開始支持)
  • 從環境參量OSA_LIBRARY_PATH中尋找,多個路徑跟PATH一樣,中間用“:”隔開。(這個也是從OSX10.11)開始支持。

首先假設我們寫了一個庫函數:

function log(message) {
    TextEdit = Application('TextEdit')
    doc = TextEdit.documents['Log.rtf']
    doc.text = message
}

功能很簡單,就是利用系統的文本編輯器將輸出信息保存為一個rtf文件。以上代碼保存為文件名為toolbox.scpt的文本文件,記住腳本庫文件必須用.scpt后綴。這個庫文件我們放到~/Library/Script Libraries/路徑下。隨后可以在REPL環境下測試使用這個庫文件:

toolbox = Library('toolbox')
toolbox.log('Hello world')

這個方法是官方推薦的校本庫編寫和調用方法,實際上我們還可以用類似node.js方法,這種方法首先要自己寫一個基本的引入函數:

var require = function (path) {
  if (typeof app === 'undefined') {
    app = Application.currentApplication();
    app.includeStandardAdditions = true;
  }

  var handle = app.openForAccess(path);
  var contents = app.read(handle);
  app.closeAccess(path);

  var module = {exports: {}};
  var exports = module.exports;
  eval(contents);

  return module.exports;
};

然后程序中就可以使用類似這樣的方法來調用庫函數:

app=require('node_modules/jxapp/index.js')
app.displayAlert("text")

這個例子僅供示例,並沒有實際作用,因為上面的require函數中實際上我們已經得到了app的實例。使用node.js的庫函數的時候有兩個注意事項:

  • jxa實際並非在瀏覽器環境運行的,這一點很類似node.js的服務器端,所以要注意global和window兩個預置的變量是不存在的,可以在程序一開始設定window=this;global=this;來規避庫內部的調用。這個問題其實前幾天我們說AngularJS2的時候也提到了。
  • 調用node.js庫,目前主要還是使用Browserify來實現的,所以要提前使用安裝相關包:
npm install -g browserify   
npm install coffeeify lodash  coffeescript

具體的使用方法可以參考上面資源鏈接中的例子,這里就不展開了。

作為mac電腦上最犀利的自動化工具,如果不想大動干戈用Xcode寫ObjectC或者Swift的話,jxa腳本還是非常值得推薦的技術手段,如果一直在mac環境生存的話,建議及早試吃。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM