A Swift 6 wrapper for the D-Bus C library with support for modern Swift concurrency.
DBusSwift is a Swift package that provides a Swift-friendly interface to D-Bus, a message bus system used for interprocess communication on Linux systems. This library enables Swift applications to communicate with system services and other applications on Linux.
- Modern Swift 6 API with full async/await support
- Proper memory management with automatic resource cleanup
- Type-safe argument handling
- Support for method calls, signals, and replies
- Comprehensive error handling
- Fully documented API with DocC comments
- Swift 6.0 or later
- libdbus-1-dev package installed
DBusSwift is designed specifically for Linux environments where D-Bus is natively available. D-Bus is a core component of Linux desktop environments and is not natively supported on other platforms.
For development and testing on non-Linux platforms, a Docker environment is provided:
# Run tests in Docker
./run-tests-in-docker.sh
This will build a Docker container with all necessary dependencies and run the test suite in a Linux environment.
Add the following to your Package.swift
file:
dependencies: [
.package(url: "https://github.com/apache-edge/dbus.git", from: "0.0.1")
]
Then add the dependency to your target:
.target(
name: "YourTarget",
dependencies: ["DBusSwift"]),
If you're developing applications with DBusSwift or building the package from source, you need the D-Bus development package:
sudo apt-get install libdbus-1-dev
If you're only running applications that use DBusSwift (e.g., distributing a compiled application), you only need the runtime library:
sudo apt-get install libdbus-1-3
import DBusSwift
// Connect to the session bus
let sessionBus = try DBusAsync(busType: .session)
// Or connect to the system bus
let systemBus = try DBusAsync(busType: .system)
// Call ListNames method on the D-Bus service
let result = try await sessionBus.call(
destination: "org.freedesktop.DBus",
path: "/org/freedesktop/DBus",
interface: "org.freedesktop.DBus",
method: "ListNames"
)
// The result is an array of Any type, but we know it's an array of strings
if let services = result.first as? [String] {
print("Available D-Bus services:")
for service in services {
print("- \(service)")
}
}
// Emit a signal
try await sessionBus.emitSignal(
path: "/org/example/Path",
interface: "org.example.Interface",
name: "ExampleSignal",
args: ["Hello from Swift!", 42],
signature: "si"
)
// Call GetConnectionUnixProcessID to get the PID of a connection
let result = try await sessionBus.call(
destination: "org.freedesktop.DBus",
path: "/org/freedesktop/DBus",
interface: "org.freedesktop.DBus",
method: "GetConnectionUnixProcessID",
args: ["org.freedesktop.DBus"],
signature: "s"
)
if let pid = result.first as? UInt32 {
print("The D-Bus daemon's PID is: \(pid)")
}
do {
let dbus = try DBusAsync(busType: .session)
// Use dbus...
} catch let error as DBusConnectionError {
switch error {
case .connectionFailed(let reason):
print("Connection failed: \(reason)")
case .messageFailed(let reason):
print("Message failed: \(reason)")
case .invalidReply(let reason):
print("Invalid reply: \(reason)")
}
} catch {
print("Other error: \(error)")
}
DBusSwift maps D-Bus types to Swift types as follows:
D-Bus Type | Signature | Swift Type |
---|---|---|
Byte | y | UInt8 |
Boolean | b | Bool |
Int16 | n | Int16 |
UInt16 | q | UInt16 |
Int32 | i | Int32 |
UInt32 | u | UInt32 |
Int64 | x | Int64 |
UInt64 | t | UInt64 |
Double | d | Double |
String | s | String |
Object Path | o | String |
Signature | g | String |
Array | a | [Any] |
Variant | v | Any |
DBusSwift includes comprehensive tests using Swift Testing. The tests are designed to run on Linux.
swift test
This project is available under the Apache License 2.0. See the LICENSE file for more info.