Building IoT Device Clients in Swift with TinyTBDeviceClient

Title image for TinyTBDeviceClient, showing a Raspberry Pi client device connected to a ThingsBoard server with an IoT dashboard in the background. A glowing padlock indicates a secure connection.
Title image created by the author using AI image generation tools.

As I work a lot in the field of IoT, I recently experimented with Swift on a Raspberry Pi. I also wanted to use it as a client device pushing telemetry data to my ThingsBoard server.

Instead of reaching for Python as usual, I wanted to explore whether Swift could serve as a serious IoT device language on Linux. That led me to evaluate mqtt-nio, where I implemented a device client that supports the most common ThingsBoard device features:

  • Connect / Disconnect
  • Push Telemetry / Subscribe to topics
  • Listen and respond to RPCs (e.g. initiated through buttons and switches on a Dashboard)

While mqtt-nio is a powerful and flexible MQTT implementation, it is intentionally generic. When working specifically with ThingsBoard devices, a lot of boilerplate logic repeats across projects, such as telemetry topics, attribute subscriptions, RPC handling, TLS configuration, etc. To make my life easier for future IoT projects, I put this into a Swift PM library I’d describe like this:

TinyTBDeviceClient is a minimal, pragmatic MQTT client written in Swift and built on top of mqtt-nio. It is pre-configured for ThingsBoard device connectivity and secure by default through mandatory TLS and CA pinning. It handles the common tasks such as publishing telemetry messages (time-series data), subscribing to topics (e.g. attribute changes), and handling RPC requests. The goal is to reduce the complexity of MQTT when integrating IoT devices with ThingsBoard, offering a more focused and manageable approach.

The library is intentionally small and focused – it is not a general-purpose MQTT abstraction layer.

πŸ“ Resources

πŸ’» Quick Facts

  • Tiny MQTT client library, designed for IoT client devices working with ThingsBoard
  • Built on top of mqtt-nio (SwiftNIO)
  • Pre-configured for ThingsBoard server connectivity
  • TLS enforced by default, requires CA pinning
  • Runs on macOS, iOS, Linux (successfully tested on Raspberry Pi), and anywhere nio-mqtt is supported

πŸ›« Quickstart

let eventLoopGroup: EventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let eventLoopGroupNioProvider: NIOEventLoopGroupProvider = .shared(eventLoopGroup)

client = try TinyTBDeviceClient(
        host: "your-iot-cloud.com",
        port: 8883,
        clientId: "your-client-01-id",
        caCertPath: "/path/to/your/server-ca-cert.pem",
        username: "your-client-username",
        password: "yourSuperSecretPassword",
        eventLoopGroupProvider: eventLoopGroupNioProvider,
        logger: Logger(label: "TinyTBDeviceClient")
)

client.connect(
    onSuccess: {
            client.publish(
                    message: #"{ "testMessage": "Hello ThingsBoard at \#(Date())"}"#,
                        to: "v1/devices/me/telemetry"
            )
        })

client.disconnect()

⌨️ Sample Implementation

For my own references, I coded a sample implementation making use of the above described functionality: TinyTBDeviceClient-Example

Therefore, I created a dashboard on my ThingsBoard tenant which displays three different random numbers, each published by the client device. Random number one and two can be updated by pushing the corresponding buttons, random number three gets updated automatically when activated through the switch.

My ThingsBoard sample Dashboard for my TinyTBDeviceClient reference implementation

The sample implementation mainly consists of two files showcasing the library’s features and functionality:

Follow the steps in the README to get started.

πŸ” SSL / TLS

In case you need to set up your own PKI for your MQTT or ThingsBoard server, look at the related post on my blog: Building a Secure PKI for MQTT using OpenSSL