オートメーション

プリセットや自分のルールで、保存した設定を置き換えずに入力中のキーボードを変更できます。

状態ルールは、条件を満たしている間だけ一時的な設定を適用します。向き、ウインドウ幅、外観、言語、配列、入力欄の属性、時刻、プラグインが宣言した状態を組み合わせられます。すべての条件が必要か、いずれかの条件でよいかを選びます。コンテキストが不明な場合、否定条件を満たしたとは扱いません。

イベントルールは、キーボードを開いたとき、言語や入力欄の属性が変わったとき、プラグインがイベントを発行したとき、ショートカットをタップしたときに実行されます。コマンドはイベントごとに1回実行されます。設定の上書きは、キーボードを閉じる、ルールを変更する、セッションの上書きを消去するまで続きます。

保存した設定がいつも基本

ルールは現在の保存設定に重ねて適用されます。ドラッグして優先順位を変更でき、後のルールが優先されます。ルールをオフにすると、そのルールによる変更がなくなります。一時的な上書きが終わっても、途中で保存した変更は残ります。プロファイルのアクションは一時的で、保存したプロファイルの選択や書き換えは行いません。

コンパクトのプリセットは、既存のサイズ制限内で、キーの行を28ポイント、幅を保存値の80%にします。分割を有効にすると、小さくなったキーの分だけ中央の余白が広がり、左右のキーは端の近くに保たれます。片手モードは独自の配置を維持します。割合は常に保存値を基準とし、繰り返し適用しても縮小が累積しません。

プレビューは自分で選んだサンプルの状況を使います。コマンドを実行せず、条件の一致、無効な参照、適用予定の設定を表示します。アプリのプレビューは実際のキーボードの状態とは別です。上部バーにオートメーションを追加すると、有効な上書きの確認やショートカットルールの実行ができます。

イベントが発生したとき

イベントが発生したとき

  • keyboard.open
  • keyboard.close
  • keyboard.languageChanged
  • keyboard.layoutChanged
  • keyboard.profileChanged
  • keyboard.planeChanged
  • input.changed
  • time.minute
  • user.run

アクション

  • panel.close
  • plane.letters
  • plane.numbers
  • plane.symbols
  • overrides.clear
  • panel.emoji
  • panel.calculator
  • panel.conversion
  • panel.layouts
  • panel.profiles

評価はキーボードが動作している間に行われます。時刻ルールはバックグラウンドでは動作せず、終了イベントの発生も保証されません。Clinkは使用先のアプリを識別したり、iOSの設定を変更したりできません。使用する機能のメンバーシップ、フルアクセス、ユーザーのタップの要件は維持されます。読み込みによって権限が付与されることはありません。

プラグインの契約

.clinkpluginファイルの任意のautomationオブジェクトで、イベント、状態、設定、コマンド、プリセット、ショートカット枠を宣言します。各要素には固定ID、完全一致が必要なスキーマバージョン、ローカライズされたタイトルがあります。ホストがplugin/<plugin-id>/<kind>/<id>という名前を作成します。プラグインはコアや別のプラグインの名前空間を使用できません。

公開状態、イベントデータ、コマンド引数は、真偽値、範囲を定めた数値、宣言済みの選択肢を受け付けます。設定では長さを制限したテキストも使えます。状態と設定は、プラグインの既存の状態辞書のキーを使います。一時的な値は保存前に元に戻されます。プリセットは通常の無効なルールで、明示的な選択が必要です。

プラグイン ›

フック

フック呼ばれるタイミング
on_automation(command, args, state)on_automation(command, args, state)は、既存のサンドボックスで承認済みのローカルコマンドを実行します。スペースバーの表示更新、宣言済み状態の公開、宣言済みイベントの発行が可能です。このフックでは、テキスト挿入、クリップボードへのアクセス、永続的な設定変更、外部リクエストは許可されません。
automation_emit(name, payload)宣言済みイベントを型付きデータとともに発行します。ホストがプラグインの名前空間とスキーマバージョンを付与します。スクリプト側でユーザー操作や実行チェーンの履歴を指定することはできません。
automation_publish(name, value)条件で使う宣言済みの状態値を1つ公開します。値はキーボードのセッション終了時、またはプラグインが利用できなくなったときに消去されます。
automation_run(slot)プラグインのネイティブ操作部品のアクションハンドラーから呼び出します。ユーザーがオートメーションで、宣言されたショートカット枠をルールに割り当てます。プラグインが勝手にルールを選んだり、タップが必要なコマンドをタイマーから実行したりすることはできません。

アクション

  • space_text
  • automation_emit
  • automation_publish

宣言済みイベントと安全なコマンド

このマニフェストの断片は、通常のプラグインファイルのautomationフィールドに記述します。スクリプトはキーボードの準備状態を公開し、イベントを発行して表示を更新します。エディタでそのイベントを選び、ready状態を条件にしてcaptionコマンドを選択してください。この例を読むだけでプラグインがインストールされたり、有効になったりすることはありません。

{
  "schemaVersion": 1,
  "events": [
    {
      "id": "ready",
      "title": {
        "en": "Keyboard ready"
      },
      "version": 1,
      "payload": [
        {
          "id": "ready",
          "key": "ready",
          "title": {
            "en": "Ready"
          },
          "version": 1,
          "type": "bool",
          "choices": [],
          "minimum": 0,
          "maximum": 100,
          "defaultValue": null
        }
      ]
    }
  ],
  "state": [
    {
      "id": "ready",
      "key": "ready",
      "title": {
        "en": "Ready"
      },
      "version": 1,
      "type": "bool",
      "choices": [],
      "minimum": 0,
      "maximum": 100,
      "defaultValue": null
    }
  ],
  "settings": [
    {
      "id": "show_caption",
      "key": "show_caption",
      "title": {
        "en": "Show caption"
      },
      "version": 1,
      "type": "bool",
      "choices": [],
      "minimum": 0,
      "maximum": 100,
      "defaultValue": true
    }
  ],
  "commands": [
    {
      "id": "caption",
      "title": {
        "en": "Refresh caption"
      },
      "version": 1,
      "arguments": [],
      "behavior": "localUI",
      "requiresUserGesture": false,
      "requiresFullAccess": false
    }
  ],
  "presets": [],
  "shortcuts": [
    "run"
  ]
}
def initial():
    return {"ready": False, "show_caption": True}

def on_open(state):
    state["ready"] = True
    automation_publish("ready", True)
    automation_emit("ready", {"ready": True})
    return state

def on_automation(command, args, state):
    if command == "caption":
        space_text("Clink" if state["show_caption"] else None)
    return state

def bar_items(state):
    return [bar_button("run", "Run automation", icon="bolt.circle")]

def on_action(action, value, state):
    if action == "run":
        automation_run("run")
    return state

内容を確認してルールを共有

オートメーションからJSONを読み込み、書き出せます。読み込んだルールはオフの状態で新しい識別子を持ち、テーマ、配列、プラグインへの参照を保持します。参照先がない場合は、実行前に復元する必要があります。ルールは全体で共有され、必要に応じてプロファイルに限定できます。プロファイルの書き出しやiCloud同期とは別に保存されます。

{
  "schemaVersion": 1,
  "shortcutBindings": {},
  "rules": [
    {
      "id": "landscape-split",
      "name": "Landscape split",
      "enabled": false,
      "schemaVersion": 1,
      "kind": "state",
      "trigger": "keyboard.open",
      "triggerVersion": 1,
      "cooldownSeconds": 1,
      "conditions": {
        "mode": "all",
        "items": [
          {
            "id": "landscape",
            "field": "interface.orientation",
            "comparison": "equals",
            "value": "landscape",
            "upper": null,
            "hysteresis": 0,
            "version": 1
          }
        ]
      },
      "actions": [
        {
          "id": "split",
          "kind": "set",
          "target": "layout.split",
          "value": true,
          "version": 1
        }
      ]
    }
  ]
}

スキーマと制限

バージョン1は、最大128個のルール、ルールごとに24個の条件と32個のアクション、最大1,048,576バイトの読み込みに対応します。設定レジストリには268個の対象があり、39個の除外項目が文書化されています。無効な設定のまとまりは全体が拒否されます。コマンドは最初の失敗で停止し、それ以前の処理の取り消しは保証しません。

プラグインの要素が削除、無効化、非互換になると、依存するルールは利用できなくなります。クラッシュやタイムアウトでは、失敗した要素がそのセッション中は無効になります。コマンドには20,000ステップと短い実行時間の制限があります。キュー、実行間隔、チェーン長の制限と状態の安定化により、イベントが無限に繰り返されるのを防ぎます。

ウィジェット

Clink にはホーム画面ウィジェットが3つと Live Activity が1つあります。プロファイル切り替え、入力の統計、クイック音声入力、そして音声入力セッションそのものです。

ウィジェットは共有の設定ファイルを直接読むので、アプリを閉じていても動き続けます。

App Intents

現在は2つあり、どちらもアプリを開きません。Switch Keyboard Profile はウィジェットから共有設定を書き換え、すでに表示されているキーボードがその場で変更を受け取ります。End Dictation は Live Activity からマイクのセッションに届き、必要ならアプリをバックグラウンドで起動します。

自分で作ったプロファイルへの切り替えにはメンバーシップが必要で、この確認はウィジェットの中でも行われます。Clink に付属するプロファイルは無料です。

Clink は独自のショートカットのフレーズを定義していないため、声に出して呼ぶものはありません。

ファイルを開く

Clink は自分のファイル形式をiOSに登録しているので、ファイル、AirDrop、メッセージ、どの共有シートからでも Clink で開けます。

App Storeでダウンロード