最近開通了我的技術博客,不定期更新一些學習和感受,目前主要是iOS,明年預期會更新一些Web端以及Flutter的內容~
文檔鎮(zhèn)樓:AppleScript Language Guide
前言
筆者學習AppleScript的起因,是因為本人鍵盤修飾鍵的使用習慣和其他同事不同,筆者習慣于將"大小寫修飾鍵"和"Ctrl鍵"互調位置,以至于習慣默認修飾鍵配置的同事在我的電腦上進行調試,總是忍不住感嘆一聲:
“這TM是人用的嗎?”
相信了解iOS開發(fā)的小伙伴們都知道,Ctrl + Command + 上下,可以切換.h和.m文件,但是在筆者的鍵盤上,執(zhí)行這一操作時,不但沒有任何的效果,NM還會把鍵盤設置成了大寫模式,在一次又一次,怒吼的咆哮后,筆者痛定思通,決心要解決這個問題,在如何不改變自己鍵盤使用習慣的前提下,讓來調試代碼的同事們也感到如使用自己鍵盤般的流暢和絲滑呢?于是,就有就有了這篇
聊一聊腳本語言:AppleScript
AppleScript的實踐應用
實踐:還原修飾鍵默認設置
本文下面比較詳細地介紹了AppleScript基礎知識,在學習它們之前,只需要簡單了解AppleScript中常用的幾個概念,就可以實現GUI Scripting的神奇功效,我們先來看看AppleScript中的常用概念
AppleScript的常用概念
這是一個神奇的傳送門?腳本編輯器(本文所有代碼均可直接在IDE中執(zhí)行)
我們先了解下我們的IDE工具,打開腳本編輯器
點擊圖片中的按鈕,可以看到上面除了"結果"選項外,還多出了"信息"、"事件"和"回復"三個選項,在這里面可以看到更為詳細的打印信息!
AppleScript的必須掌握的命令:
- tell someone do something
AppleScript的語法十分接近自然語言,想要操作一個對象執(zhí)行某些操作,只需要使用"tell命令 +對象類型 + 對象名",在之后執(zhí)行end tell
,結束當前的回話
激活終端
tell application "Terminal"
activate -- 告訴 終端,執(zhí)行激活命令
end tell
關閉終端
tell application "Terminal"
quit -- 告訴 終端,執(zhí)行退出命令
end tell
System Events是系統(tǒng)應用,我們有時寄期望于在系統(tǒng)應用中找到某個正在執(zhí)行的進程(Process)
tell application "System Events"
tell process "Terminal"
end tell
end tell
在執(zhí)行這段代碼后,你會發(fā)現,其實什么都沒有執(zhí)行,不用慌,這是因為你并沒有告訴"終端"要做些什么,那么我們通過entire contents
命令獲取Terminal內的所有UI元素
#執(zhí)行下面代碼前,先激活"終端"
tell application "System Events"
tell process "Terminal"
entire contents --獲取區(qū)域內所有的UI元素
end tell
end tell
執(zhí)行后,會得到"終端"內的所有UI元素的完整描述
選擇日志中的一條進行分析
button 1 of window "終端 — -zsh — 80×24" of application process "Terminal" of application "System Events"
其實這其中的從屬關系已經十分明確了,翻譯過來就是
應用"System Events"的應用進程"Terminal"的"窗口"的"按鈕1"
- 模擬點擊
button 1的描述,我們已經很清楚了,那button 1到底對應"終端"中的哪個按鈕呢?其實單從名字上看,很難看出button 1對應的是哪個按鈕,那么我們用一個很簡單的方法,確定它的位置,讓button 1執(zhí)行點擊操作,通過它的點擊效果反推它的位置!
#執(zhí)行下面代碼前,先激活"終端"
tell application "System Events"
tell process "Terminal"
(*
注意:由于環(huán)境的差異性,直接復制這段代碼到你的腳本編輯器,可能得不到想要的效果
這里一定要輸入你上面entire contents后,打印的"button 1"的完整結果
*)
click button 1 of window "終端 — -zsh — 80×24" of application process "Terminal" of application "System Events"
end tell
end tell
執(zhí)行上述操作后,發(fā)現"終端"被關閉了,原來button 1對應的就是"終端"左上角的關閉按鈕
請注意:并不是所有的button 1對應的都是應用的關閉按鈕,還要具體情況具體分析
- 模擬輸入
我們打開了終端,想看當前目錄下存有哪些文件,該如何操作呢?
想一下這個問題,我們都知道在終端中查看目錄下文件的命令是ls
,那么就可以將這個問題拆分為鍵入'ls'和點擊回車兩個步驟
在AppleScript中,輸入字符串的命令是keystroke
,你也可以用key code
實現單鍵點擊
我們完善一下代碼:
tell application "Terminal"
activate
end tell
tell application "System Events"
tell process "Terminal"
keystroke "ls"
delay 1 -- 延時一秒后執(zhí)行
key code 36 -- 回車的鍵位碼為36
end tell
end tell
完整的鍵位碼傳送門?鍵位碼
我們有時需要通過組合按鍵的方式執(zhí)行某一操作,通過在鍵入命令后添加using {按鍵A down, 按鍵B down}
的方式,如:
#強制關閉應用快捷鍵
key code 53 using {command down, option down} -- Esc的鍵位碼為53
- 執(zhí)行shell命令
在終端中通過執(zhí)行shell命令的方式可以達到和模擬鍵入的同樣的效果
tell application "Terminal"
activate
do script "ls"
end tell
當然也可打開某路徑下的文件,這里我們嘗試打開"系統(tǒng)偏好設置"中的"鍵盤偏好設置"
tell application "Terminal"
activate
#打開鍵盤偏好設置
do script "open . '/System/Library/PreferencePanes/Keyboard.prefPane'"
end tell
我們簡單回顧一下,現在我們已經了解了:
如何激活應用,并在當前的系統(tǒng)進程中找到它
如何獲取某一區(qū)域內的全部UI控件,并嘗試點擊其中的某一個單獨控件
如何實現模擬字符串輸入、單鍵輸入和組合輸入
如何關閉應用
此外,我們再多了解兩個幫助我們編寫代碼的兩個小知識點:
1.注釋
AppleScript中的注釋分為單行注釋和多行注釋
單行注釋:#
、--
多行注釋 (* 中間的部分都是注釋 *)
(上文中三種注釋均有用到)
2.輸出日志
log
命令,可以通過打印輔助信息,來幫助我們編寫代碼
至此,你已經掌握了實現恢復系統(tǒng)默認修飾鍵的全部基礎概念,小伙伴們完全可以自己嘗試寫下代碼
核心代碼:
#激活
tell application "Terminal"
activate
#打開鍵盤偏好設置
do script "open . '/System/Library/PreferencePanes/Keyboard.prefPane'"
end tell
tell application "System Events"
tell process "系統(tǒng)偏好設置"
#點擊修飾鍵
click button "修飾鍵…" of tab group 1 of window "鍵盤" -- of application process "System Preferences" of application "System Events"
#更改為默認狀態(tài)
click button "修飾鍵…" of tab group 1 of window "鍵盤" -- of application process "System Preferences" of application "System Events"
click button "恢復成默認" of sheet 1 of window "鍵盤" -- of application process "System Preferences" of application "System Events"
click button "好" of sheet 1 of window "鍵盤" -- of application process "System Preferences" of ?application "System Events"
end tell
end tell
AppleScript基礎知識
1.基本模塊
語法
#符號'?'(option+'L') 用來將語句延續(xù)到第二行
display dialog "This is just a test." buttons {"Great", "OK"} ?
default button "OK" giving up after 3 --result:調出彈窗,默認鍵是OK,3秒后消失
變量和屬性
#變量賦值
set myName to "John"
copy 22 to myAge
#局部變量
local windowCount
local agentName,agentNumber,agentHireDate
#全局變量
global gAgentCount
global gStatementDate,gNextAgentNumber
#屬性
property defaultClientName : "Mary Smith"
#字符串中引用變量
set aPerson to "GCS"
display dialog "Hello " & aPerson & "!"
類型轉換
set myText to 2 as text
運算符
3 * 7 - "1" --result 20
List(數組)
#初始化數組
set myList to {1, "what", 3} --result: {1, "what", 3}
set beginning of myList to 0 --首位設置為0
set end of myList to "four" --末位設置為"four"
set item 2 of myList to 4 --第二位設置為4
myList --result: {0, 4, "what", 3, "four"}
Record(鍵值對)
#存值
set myFullName to {firstName:"John", lastName:"Chapman"}
#取值
set myLastName to lastName of myFullName --result "Chapman"
2.控制語句
considering/ignoring
"Hello Bob" = "HelloBob" --result: false
ignoring white space --忽略空格
"Hello Bob" = "HelloBob" --result: true
end ignoring
"BOB" = "bob" --result: true
considering case --考慮大小寫
"BOB" = "bob" --result: false
end considering
try-error
try
word 5 of "one two three"
on error
error "There are not enough words."
end try
if
set currentTemp to 10
if currentTemp < 60 then
set response to "It's a little chilly today."
else if currentTemp > 80 then
set response to "It's getting hotter today."
else
set response to "It's a nice day today."
end if
display dialog response
repeat-exit
set num to 0
repeat
-- perform operations
if num < 5 then
set num to num + 1
else
display dialog num
exit repeat
end if
end repeat
repeat (number) times
set x to 3
set power to 3
set returnVal to x
repeat power - 1 times
set returnVal to returnVal * x
end repeat
return returnVal
repeat while(當型循環(huán))
set userNotDone to true
repeat while userNotDone
set userNotDone to enterDataRecord()
end repeat
on enterDataRecord()
delay 3
false
end enterDataRecord
repeat with loopVariable
數值循環(huán)
set n to 3
set returnVal to 0
repeat with i from 0 to n
set returnVal to returnVal + I
end repeat
return returnVal
(數組遍歷)
set peopleList to {"Chris", "David", "Sal", "Ben"}
#方法一
repeat with aPerson in peopleList
display dialog "Hello " & aPerson & "!"
end repeat
#方法二
repeat with i from 1 to (number of items in peopleList)
display dialog "Hello " & item i of peopleList & "!"
end repeat
String to List
set wordList to words in "Where is the hammer?"
repeat with currentWord in wordList
log currentWord
if (contents of currentWord) is equal to "hammer" then
display dialog "I found the hammer!"
end if
end repeat
record遍歷
#在文檔中沒有找到遍歷record的方法,不知道是不是不小心遺漏了
#但是在Stack Overflow中看有如下方法,引入了OC中的Foundation庫,實現了record的遍歷
use framework "Foundation"
set testRecord to {a:"aaa", b:"bbb", c:"ccc"}
set objCDictionary to current application's NSDictionary's dictionaryWithDictionary:testRecord
set allKeys to objCDictionary's allKeys()
repeat with theKey in allKeys
log theKey as text
log (objCDictionary's valueForKey:theKey) as text
end repeat
3.函數構造
on greetClient(nameOfClient)
display dialog ("Hello " & nameOfClient & "!")
end greetClient
greetClient("GCS_DEVELOPER")
4.腳本對象
定義/執(zhí)行腳本
script John
property HowManyTimes : 0
to sayHello to someone
set HowManyTimes to HowManyTimes + 1
return "Hello " & someone
end sayHello
end script
tell John to sayHello to "Herb"
#John's sayHello to "Jake" --result: "Hello Jake"
#sayHello of John to "Jake" --result: "Hello Jake"
初始化腳本
on makePoint(x, y)
script thePoint
property xCoordinate:x
property yCoordinate:y
end script
return thePoint
end makePoint
set myPoint to makePoint(10,20)
get xCoordinate of myPoint --result: 10
get yCoordinate of myPoint --result: 20
繼承
script Alex
on sayHello()
return "Hello, " & getName()
end sayHello
on getName()
return "Alex"
end getName
end script
script AlexJunior
property parent : Alex
on getName()
return "Alex Jr"
end getName
end script
-- Sample calls to handlers in the script objects:
tell Alex to sayHello() --result: "Hello, Alex"
tell AlexJunior to sayHello() --result: "Hello, Alex Jr."
tell Alex to getName() --result: "Alex"
tell AlexJunior to getName() --result: "Alex Jr"
寫在結尾
本文記錄的只是AppleScript中的一小部分內容,筆者在網上暫時還沒有找到十分詳細的中文文檔和介紹,所以想要更加深入的了解和學習AppleScript還是查看官方文檔!
一手資料?AppleScript Language Guide
參考資料:
手把手教你用 AppleScript 模擬鼠標鍵盤操作,實現 macOS 系統(tǒng)的自動化操作
AppleScript中的保留字