SwiftHooks is a modular event-driven programming framework for Swift, that allows you to listen for both generic and specific events, with a builtin command system. All with a SwiftUI inspired API design.
SwiftHooks is built on a couple of core concepts/types:
- Hooks: A
Hook
within SwiftHooks is a backend implementation emitting events. For example Discord, Slack or GitHub - SwiftHooks: This is the main class that acts as a traffic control and connection hub of sorts.
Hooks
andPlugins
are both connected to the mainSwiftHooks
class. - Plugins: A
Plugin
containsCommands
andListeners
, usually grouped by purpose and can be registered to the mainSwiftHooks
class. - Commands: A
Command
is a specific function to be executed on specific message events. For example/ping
. - Listeners: A
Listener
defines a callback for certain events. For examplemessageCreate
ormessageUpdate
.
Hooks are simple in architecture. They need the ability to:
- Boot and connect to their specific backend.
- Have listeners attached to them.
- Emit events back to the main
SwiftHooks
instance.
The emitting back to SwiftHooks
is important for so called "Global" events. Global events are generic events that can be emitted by multiple backends. A great example of this is messageCreate
, supported by Discord, Slack, GitHub and loads more. This allows you to create one listener that acts on multiple platforms.
SwiftHooks is available through SPM. To include it in your project add the following dependency to your Package.swift
:
.package(url: "https://github.com/MrLotU/SwiftHooks.git", from: "1.0.0-alpha")
For a full example see the Example repository.
To get started create an instance of SwiftHooks
.
let swiftHooks = SwiftHooks()
After that, attach your first hook:
swiftHooks.hook(DiscordHook.self, DiscordHookOptions(token: "discord_token"))
This will set up your system to connect to Discord, and stream events to your program.
To add listeners and commands, create a pluign:
class MyPlugin: Plugin {
var commands: some Commands {
Group {
Command("echo")
.arg(String?.self, named: "content")
.execute { (hooks, event, content) in
event.message.reply(content ?? "No content provided")
}
Command("ping")
.execute { (hooks, event) in
event.message.reply("Pong!")
}
}
}
var listeners: some EventListeners {
Listeners {
Listener(Discord.guildCreate) { event, guild in
print("""
Succesfully loaded \(guild.name).
It has \(guild.members.count) members and \(guild.channels.count) channels.
""")
}
GlobalListener(Global.messageCreate) { event, message in
print("Message: \(message.content)")
}
}
}
}
For a more complex Plugin example check the Example repository.
After your plugin is created, register it to the system and run.
try swiftHooks.register(MyPlugin())
try swiftHooks.run()
Calling swiftHooks.run()
will block the main thread and run forever.
All contributions are most welcome!
If you think of some cool new feature that should be included, please create an issue. Or, if you want to implement it yourself, fork this repo and submit a PR!
If you find a bug or have issues, please create an issue explaining your problems, and include as much information as possible, so it's easier to reproduce & investigate (Framework, OS and Swift version, terminal output, etc.)