2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Swift で Stream Deck のプラグインを作る

Last updated at Posted at 2025-09-17

本記事は iOSDC Japan 2025 で話した内容を、詳細に書いたものです

はじめに

Stream Deck のプラグイン作成が思っていたよりも大変だったので、また作る時のためにメモがてら残そうと思って記事を書きましたmm

元から情報が少ない上に、Swift で動かそうとする人がほぼいないため、手探りで動かす感じになりました。笑

特に開発を初めてしまえば、そんなに大変ではないのですが、最初のセットアップとデモを動かすまでが少し面倒だったので、今回はその部分をまとめています。

※ ちなみに Mac(Apple Silicon) でしか試していませんのであしからず

Stream Deck に関して

物理ボタンなどにアクションを色々と登録して、ワンアクションでパソコン上の何かに指示を与えたりできるデバイスです。

結構いろんな種類が出ています。

私が持っているのは、以下の Stream Deck + というもので

多くのアプリが Stream Deck に対応したプラグインを出しており、公式のマーケットからダウンロードして使うことが可能です。

プラグインの仕組みとしては、PC上にインストールした Stream Deck 公式アプリがプラグインと Websocket でやりとりを行っています。(下記はざっくりした図)

プラグインに対応している外部アプリは、そのプラグインとやりとりできるように、RESTやSocketで個々に通信方法を実装しているといった具合です。

今回は、上記で説明したプラグインを自分で作ってみるというお話です。

Stream Deck SDK に関して

プラグインは先ほど説明した図にあるように、Stream Deck アプリに必要な通信プロトコルへ準拠している必要があります。つまり、準拠さえすればどんな言語でも作成することは可能です。(そのはず)

そして、公式の SDK はその実装をテンプレート化してくれているので、準拠するだけで簡単に実装することができるのです。

最新の SDK では Typescript を例にしており、ドキュメントもそのようになっています。

公式の古いリポジトリでは

  • Javascript
  • C++
  • Objective-C

で作成したテンプレート例が残っており、こちらも参考にしても良いでしょう。

Swift では StreamDeckPlugin という公式を元にしたライブラリがあり、今回はこちらを使用していきます。

StreamDeckPlugin に関して

reddit に残っているコメントいわく、Swift 対応のSDKコードがないので作ってみたそうです。(すごい笑)

先Objective-C のサンプルコードは残っているので、こちらを使えば動かせなくはないですが、せっかくなら Swift で書きたいのでありがたく使わさせていただきます!

↑ 2019年製で一応動作するように設定ファイルとかはメンテされているっぽい


注意点として、個人でメンテされているので、全ての Stream Deck 端末に対応しているかどうかわかりません。(私の Stream Deck + は2023年にサポートのコードが入っていました。)

サンプルコードを試す

README に書いてあることをやっても上手く動かなかったので、試しにサンプルコードを Stream Deck 上で動かすところからやっていきましょう。

手順

0. セットアップ

お持ちの Stream Deck ごとに対応している公式アプリがあるので、事前にダウンロードしてください。(普通に使うためにインストールしていると思いますが)

1. サンプルコードの準備

サンプルコードは SDK に含まれているので、SDK ごとリポジトリをクローンします。(サンプルだけ取ってきてもOK)

その際、現状(2025年5月付)リリースされているバージョン 0.5.1main ブランチの中身が違うため、サンプルコードのビルドができません
(開発者が新規の実装を全部 main につっこんでいるため...😂)

なので、クローンしてきたブランチのタグから、0.5.1 のブランチに戻してください。

2. ビルドできる状態にする

Stream Deck では、Swift のコードをそのまま動かすのではなく、コンパイルしてバイナリになったものを呼び出しています。

つまり、バイナリとしてビルドできるように、パッケージを開いて StreamDeckPlugin と関連する SPM ライブラリを先に取得します。

ライブラリごとクローンしている場合は、
リポジトリ > Examples > counter > Package.swift
にある Package.swift をクリックして開いてください。

Package.swift の中にある dependencies のパスを直して、依存しているライブラリを取得してください。このとき、依存関係のバージョンは先ほど取ってきたタグ(0.5.1)のバージョンの直してください。

-> .package(url: "https://github.com/emorydunn/StreamDeckPlugin.git", from: "0.5.1")

念の為、なんでもいいので(とりあえず、My Mac を指定)ビルドしてみてください。成功した場合は、サンプルのプラグインコードをバイナリとして書き出していきます。

3. 実行ファイル(バイナリ)の書き出し

ターミナルで Package.swift があるディレクトリに移動して、Swift のコマンドでビルドします。(初回のみ数分かかる時がある)

.bash
swift build -c release
Mac の設定によって細かく分けたい場合

必要に応じてオプションをつけてください。

.bash
echo "Building ARM binary"
swift build -c release --arch arm64
.bash
echo "Building Intel binary"
swift build -c release --arch x86_64

もし、エラーが出た場合は、エラー箇所が出るのでコードを直してください。

上手くいけば隠しフォルダとして .build が同じディレクトリにできていると思います。色々作成されたと思いますが、必要なのは実行ファイル(バイナリファイル)の1つだけです。

-> .build > arm64-apple-macosx > release > counter_plugin

実行ファイルの名前は、Package.swift で設定しているものが名前としてつけられます。arm64-apple-macosx 部分はビルドするMacによって変わると思うので、注意してください。

4. 実行ファイルの移動と設定ファイルの作成

作成した実行ファイルを、Stream Deck で読み込めるように、設定ディレクトリにコピーする必要があります。

-> ~/Library/Application Support/com.elgato.StreamDeck/Plugins

その際に、新しいディレクトリを作成する必要があり、.sdPlugin が末尾に来るという 命名規則が決まっているので、必ず守る必要があります。

デフォルトのプラグインがいくつかインストールされているので、それと同じ命名規則にしておくと良いと思います。

また、同時に設定ファイル(manifest.json)がないと読み込まれないので、SDK が用意してくれているコマンドで生成します。

.bash
.build/arm64-apple-macosx/release/YOUR_PLUGIN_NAME export ./com.YOUR_PLUGIN_NAME.sdPlugin \
  --output ~/Library/"Application Support"/com.elgato.StreamDeck/Plugins \
  --generate-manifest \
  --copy-executable

YOUR_PLUGIN_NAME のところは任意の名前に直してください。

コマンドのドキュメントは SDK の README を見てくださいmm

最終的にプラグインの中身がこのようになっていれば大丈夫です。

  • Swiftの実行バイナリファイル(上記では counter-plugin)
  • レイアウトファイル
  • 設定ファイル(manifest.json)

manifest がないと Stream Deck にアプリが読み込まれないので忘れ時に設置しましょう。

5. プラグインの実行

あとはプラグインをボタンとして設定するだけです。もし、Stream Deck のアプリを開いている場合は、一度 kill してください。

再度開くとプラグインが追加されているはずです。

完全に読み込まれるのに、数秒かかるので少しだけ待ってください

サンプルアプリには

  • 数字のカウンター増加ボタン
  • 数字のカウンター現象ボタン
  • 数字のカウンターのつまみ制御

の三つが含まれています。

本体のボタンを押したりトグルを回すと、無事カウントのサンプルコードが動きます!
(長押しするとリセット)

プラグインを再インストールする場合、読み込み時にうまくいかないことがあります。その時はキャッシュを削除したり、UUIDを変更することで新しく読み込まれたりする場合があります。


サンプルコードが動いたなら、あとは簡単です。
処理の部分を、自分で独自の実装にするだけですね!

今回はレイアウトやライフサイクルの説明は省いていますが、そこまで多くないので、ライブラリのドキュメントを直接見てほらう方が早いかと思いますmm

開発Tips

- ログの調査

動作しているのかをチェックするために、はき出されるログを追うこと関数の実装を確認できます。ログは独自に定義された logMessage メセッドを呼び出すだけです。

【example】

例えば、プラグイン読み込み時にログを入れてみます。

.swift
init(context: String, coordinates: Coordinates?) {
    self.context = context
    self.coordinates = coordinates

    logMessage("-------init-------")
}

これらのログは、以下に出力されます。

  • Windows: %appdata%\Elgato\StreamDeck\logs\.
  • macOS: ~/Library/Logs/ElgatoStreamDeck/.

公式ドキュメントにも記載あるので、もし見つからない場合がパスが変わっている可能性もあるので、公式サイトを参照してください。

このようにプラグイン名でログが出るので見つけやすいです。

無事ログが出力されています。

ボタンの動作など、ちゃんと押されているのか確認したい場合に有効なデバッグ方法かなと思います。

- ビルドとファイル設置の自動化

ビルドしたりコピーしたりが都度大変なので....

以下のスクリプトを用意して、修正したらコマンドを叩いて自動でプラグインを更新するとデバッグが楽です。

example

build-and-install.sh
## Package.swift で設定している name と一致させること
## .executable(name: "action-plugin", ...
PLUGIN_NAME="action-plugin"

# === パス ===
BINARY_PATH=".build/release/$PLUGIN_NAME"
PLUGIN_ROOT_DIR="$HOME/Library/Application Support/com.elgato.StreamDeck/Plugins"
PLUGIN_NAME="com.elgato.$PLUGIN_NAME.sdPlugin"
PLUGIN_DIR="$PLUGIN_ROOT_DIR/$PLUGIN_NAME"

# === ビルド ===
echo "🔨 Building release binary..."
swift build -c release || { echo "❌ Build failed"; exit 1; }

# === 配置先の削除と再生成 ===
echo "🧹 Removing existing plugin directory (if exists)..."
rm -rf "$PLUGIN_DIR"
mkdir -p "$PLUGIN_DIR"

# === バイナリと定義ファイルをコピー ===
echo "📦 Copying binary..."
cp "$BINARY_PATH" "$PLUGIN_DIR/"

# === manifest の生成とプラグイン書き出し ===
echo "📄 Generating manifest and exporting plugin..."
"$BINARY_PATH" export "./$PLUGIN_NAME" \
  --output "$PLUGIN_ROOT_DIR" \
  --generate-manifest \
  --copy-executable

echo "✅ Plugin installed"

# === Stream Deck を終了(起動している場合のみ) ===
if pgrep -x "Stream Deck" >/dev/null; then
  echo "🛑 Killing Stream Deck..."
  killall "Stream Deck"
else
  echo "✅ Stream Deck is not running."
fi

最後に kill しているのは、再起動してプラグインを再読み込みを強制させるためです。

また、他にもディレクトリを簡単に開けるよう Makefile でセットアップしておくのもオススメです。

.make
# build-and-install.sh を実行するターゲット
build:
	bash build-and-install.sh

# Stream Deck プラグインフォルダを開く
open-p:
	open ~/Library/Application\ Support/com.elgato.StreamDeck/Plugins

# Stream Deck ログフォルダを開く
open-l:
	open ~/Library/Logs/ElgatoStreamDeck/

# クリーンアップ用(必要なら)
clean:
	rm -rf build/

必要なら自分でお好みのカスタマイズしてください。

サンプル

実際に動かせるものを公開しています!

Stream Deck Mobile

端末がなくても手元のアプリ試すことも可能です。

Virtual Stream Deck

また、Macアプリとしてもリリースされているので、こちらでも試すことが可能です。

終わりに

なにはともあれ、Stream Deck を自分でカスタムできるのは面白いです!

チップスにも書いてますが、コマンドを簡単に実行する環境を用意しておくと、かなり開発が捗るのでおすすめです。

レイアウト実装周りで、ライブラリのアップデートがあるそうなので、もし記事通りに動かなかったらすいませんmm

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?