StreamDeck
A library for creating Stream Deck plugins in Swift.
Usage
Your plugin class should inherit from StreamDeckPlugin, which handles the WebSocket connection and events automatically. You can override event methods in order to act upon received actions.
import StreamDeck
class CounterPlugin: StreamDeckPlugin {
var counter: Int = 0
override func keyDown(action: String, context: String, device: String, payload: KeyEvent) {
counter += 1
setTitle(in: context, to: "\(counter)")
}
}
In order to run your plugin it needs to be registered during startup. The PluginManager manages the lifecycle of your plugin. In your main.swift file add your plugin:
import Foundation
import StreamDeck
PluginManager.main(plugin: CounterPlugin.self)
This is all that should be in the file in order for the Stream Deck software to successfully launch the plugin.
Responding to Events
When events are received by your plugin they are parsed and the corresponding method is called. See the Events Received page for more details. In order for your plugin to receive the event you need to override the method.
- Note: You don't need to call
superwhen overriding, any internal responses to events are handled automatically.
Each method is called with the top-level properties along with an event specific payload. For instance, to the keyDown event provides a payload that includes the actions settings, coordinates, etc.
Sending Events
In addition to receiving events from the application your plugin can send events. Most of the commands require a context object to specify the instance on the Stream Deck.
Accessing Specific Action Instances
Responding to events is easy because the context is provided, however updating instances outside of a received event requires knowing the state of the Stream Deck.
To aid in this the StreamDeckPlugin has an InstanceManager which tracks willAppear and willDissapear events. The manager provides methods for looking up available instances in a few ways.
The most straight forward is by looking up the context token using .instance(for:). Usually you'll be looking up instances of a specific action or at specific coordinates.
To look up all instances of an action call .instances(with:) with the UUID from your manifest.json file. The ID you pass in will be automatically lowercased.
You can also look up the instance of an action by coordinates by calling .instance(at:).
The lookup methods return an ActionInstance, which provides the context, action ID, and coordinates of the instance.
Exporting Your Plugin
Your plugin executable ships with an automatic way to generate the plugin's manifest.json file in a type-safe manor, similar to SwiftPM's Package.swift.
let manifest = PluginManifest(
name: "Counter",
description: "Count things. On your Stream Deck!",
category: "Counting Actions",
author: "Emory Dunn",
icon: "counter",
version: "0.1",
os: [
.mac(minimumVersion: "10.15")
],
software: .minimumVersion("4.1"),
codePath: "counter-plugin",
actions: [
PluginAction(
name: "Increment",
uuid: "counter.increment",
icon: "Icons/plus",
tooltip: "Increment the count."),
PluginAction(
name: "Decrement",
uuid: "counter.decrement",
icon: "Icons/minus",
tooltip: "Decrement the count.")
])
PluginManager.main(plugin: CounterPlugin.self, manifest: manifest)
Using the export command you can generate the manifest file and copy the actual executable to the Plugins directory:
counter-plugin export --copy-executable --generate-manifest
You can also specify the output directory, manifest name, executable name, or preview the manifest. Check export -h for all of the options.
Adding StreamDeck as a Dependency
To use the StreamDeck library in a SwiftPM project, add the following line to the dependencies in your Package.swift file:
.package(name: "StreamDeck", url: "https://github.com/emorydunn/StreamDeckPlugin.git", .branch("main"))
Finally, include "StreamDeck" as a dependency for your executable target:
let package = Package(
// name, products, etc.
platforms: [.macOS(.v10_15)],
dependencies: [
.package(name: "StreamDeck", url: "https://github.com/emorydunn/StreamDeckPlugin.git", .branch("main")),
// other dependencies
],
targets: [
.target(name: "<command-line-tool>", dependencies: [
"StreamDeck"
]),
// other targets
]
)