日が経過しています。情報の鮮度にご注意ください
はじめに
最近新しいMac Studioを購入しました。M1 Maxチップと64GBのメモリを搭載しており、非常に高性能です。一方で、以前のブログ処理フロー]では、Craftから画像を取得する際(このステップは速いです、両者とも海外にあるため)、Tencent Cloud COSにアップロードする際にネットワークが遅い問題によく遭遇していました。

調査したところ、GithubはActionサーバーのリージョンを設定する機能をサポートしていない]ようです。このため、今後は公開プロセスをローカルで行い、ビルドプロセスを高速化することにしました。これがこの記事を書いたきっかけです。以下のAppleScriptはASと略称します。
なぜAppleScriptを選んだのか?
まず、操作の手順と複雑さを可能な限り短縮したいと考え、以下の操作手順を定めました:
- Craftの公開ボタンをクリックする。
- ローカルでビルドし、ターミナルにビルドログを表示する。
- ビルド結果をgithubにプッシュする。
あるアプリから別のアプリを呼び出す必要があるため、AppleScriptが唯一の選択肢でした。ただし、ASを使用していますが、実際に実行されるのは既存のjsファイルであり、craft_publish_ciのworkflowタスク]をローカルで実行するようにしただけです。
AppleScriptの概要
概念図:

AppleScriptでできること
- ユーザーとの対話が可能。例えばユーザー入力への応答、通知センターでの通知送信など。
- 他のアプリを制御可能。他のアプリがASインターフェースを提供している場合は直接制御でき、提供していない場合はAS構文を使用してインターフェース上のボタンなどを操作する必要があります。
- 自動化タスクの実行が可能。メール送信、タイマースクリプトの実行、音楽プレーヤーの起動、ロック画面、カスタムURL Schemeへの応答後のスクリプト実行など。
基本構文
- 行頭に
---(3つのハイフン)または#を付けると、その行がコメントになります。 (*``*xxx**``)(括弧+アスタリスク)で囲まれたxxxはブロックコメントとしてxxxの内容をコメントアウトします。- その他の基本構文は口語に似ていますが、英語の文法に自信がない場合(besides、against、overなどの具体的な意味が分からない場合)は、基本的な構文を使用することをお勧めします。
AppleScriptの形式
AppleScriptには一般的に2つの形式があります:Script(スクリプト)とApplication(アプリケーション)。ここではこの2つを紹介します。Script bundleとTextはここでは取り上げません。

注:同じコードでも、スクリプトとして保存して実行する場合とアプリケーションとして保存して実行する場合では、インターフェースが異なります。
スクリプト
スクリプトは、jsのような実行可能ファイルですが、asはMacのデスクトップ環境で実行され、jsはChromeで実行されます。ダブルクリックで実行できます。以下はスクリプトprocessが進捗を表示するインターフェースで、スクリプトの右上にある「実行」ボタンをクリックして実行します:

アプリケーション
Applicationとして保存されたASの拡張子は、Safari、Chrome、WeChatなどの通常のアプリケーションと同じで、.appで終わり、パッケージ内容を確認することもできます。URL Schemeでの呼び出し、ダブルクリック、アプリアイコンへのドラッグなど、さまざまな実行方法があります。関連するイベント関数を記述して、ユーザー操作に対応する必要があります。以下はアプリケーションprocessが進捗を表示するインターフェースで、「xxx.app」をダブルクリックして実行します:

その他
上記の2つ以外はあまり使用されませんが、スクリプトをサービスとして保存し、ステータスバーや任意のインターフェースの右クリックメニューのサービスからスクリプトを呼び出す必要がある場合は、上記以外の形式が必要です:

スクリプトをシステムServiceとして保存することを選択できます。この場合、上記のprocessコードが実行されると、進捗バーが上部のステータスバーに表示されます:

よく使われる操作コード
以下の操作は「アプリケーション」タイプのASに基づいています。以下の構文はターミナルで
osascript -e '语法内容'を使用して簡単に検証できます。ただし、process進捗バーの表示のような複数行の表現は、osascriptでは実現できません。tellのような複数行コマンドでは複数の-eパラメータをosascript -e ‘tell application “Finder”’ -e ‘end tell’のように連結して使用できますが、この構文はprocess進捗バーには無効です。
ユーザーインタラクション
通知センターに情報を表示
1 | |

ポップアップ
1 | |

ユーザー入力の取得
1 | |

注:ASではフォームのようなコンポーネントを生成することができず、上記のようなダイアログ(ウェブのpromptに類似)しか生成できません
指定テキストの再生
1 | |
その他
ユーザーにフォルダ、ファイル、色の選択やリストからの項目選択などをさせる機能は、ここでは省略します。
コマンドラインの実行
1 | |
注意:コマンドラインのPATH環境変数は
/usr/bin:/bin:/usr/sbin:/sbinであるため、nodeやnvmなど後からインストールしたコマンドを直接実行できません。これらのコマンドを実行する際は、手動でコマンドの場所を指定する必要があります。
Nodeスクリプトの実行:
1 | |
前のステートメントの出力結果を取得
直前のステートメントの直後にresultと記述することで結果を取得できます:
1 | |

デバッグ情報の表示
logステートメントを使用し、Script Editorの下にあるRepliesで出力情報を確認できます。ここではshell scriptコマンド実行中にスクリプトがコンソールに出力した内容(JSスクリプト実行時のconsole.logなど)を確認できます。
1 | |

進捗状況の表示
進捗表示にはprogressを使用しますが、状態に応じた表示が必要なため構文が複雑になります:
1 | |
関連スクリーンショットは上記で確認できます。
一定時間遅延後の実行
1 | |
nは秒数(小数可)を表します。ユーザー操作のシミュレーション時に、ページの表示遅延などに対処するために使用します。奇妙な問題も遅延実行で解決できる場合があり、このステートメントはjsのsetTimeout手法に類似しています。
他のアプリケーションの呼び出し
注意:システム警告が表示され、実行には確認が必要です:

確認後、设置-安全与隐私-隐私-自动化で確認できます:

他のアプリケーションを起動して操作を実行できます。以下はTerminalアプリを起動後、アクティブにしてコマンドを実行する例です:
1 | |
このステートメントでは、最初に開いたウィンドウが存在すればそれをアクティブにし(do script)、存在しなければ新規ウィンドウでコマンドを実行します。各do scriptは新しいTerminalを開くため、この判定によりウィンドウの再利用が可能です。ただし、window 1内に既存プロセス(例:中断されていないserver)がある場合、コマンドは実行されないため追加の判定が必要ですが、ここでは詳述しません。

URL Schemeへの応答
ASスクリプトを探してダブルクリックで起動したくない場合や、他のアプリからASアプリを呼び出したい場合にURL Schemeを使用します。少数派に](https://sspai.com/post/31500)の解説記事があります。
まずInfo.plistファイルを修正する必要があります。Script Editorの右側で「Finderで表示」を右クリック:

一つ上の階層に移動すると該当ファイルがあります:

内容はXML形式で、以下のフィールドを追加します:
1 | |
XCodeでファイルを開き、以下のようなエントリを確認:

追加成功を意味します。
この操作は、ASアプリがxhelper(既存と重複しない任意の文字列に変更可能)で始まるURLに応答するよう設定します。
設定後、Script Editorで保存するか、cmd + Lするか、一度実行する(または全て行う)ことで再コンパイルされ有効になります。
URLに応答させるため、イベントリスナーを設定:
1 | |
上記コードで、this_URLはxhelperで開いたリンクです。
ブラウザ(スクリーンショットはChrome)でリンクをテスト:

ASアプリが応答し、xhelper://你好!がポップアップ表示されます(encodeエンコード不要)。
私の使用例
ここで私のCraft buildコードを公開します。前述のURL Schemeを使用しており、nodeで実行するJSは](/tech/my-blog-ci-in-2022.html)の以前のワークフローから改造したものです。新しいロジックはなく、ASの構文は口語的で分かりやすいため解説は省略します。
1 | |
効果:

参考リンク
-
AppleScriptチュートリアル (Notionで執筆)
-
AppleScript簡易基礎チュートリアル(iDoraemon Nathan 著)
人生の重要な選択に直面したとき、最善の方法を誰かが教えてくれて、貴重な時間を無駄にせずに済めばと、私はよく願っています。だからこそ、自分の経験を踏まえて頻繁にブログを書き、広大なインターネットのこの小さな片隅に、私にとって一度きりの人生経験を記録し、助けを求める人々の力になれればと思っています。