Shared mDNS/DNS-SD service discovery for Swift — used by matter-swift and hap-swift.
mdns-swift is a pure-Swift mDNS/DNS-SD service discovery library (RFC 6762) with platform-specific backends:
- Apple platforms —
NWBrowserfor browsing/resolving,DNSServiceRegisterfor advertising (supports DNS-SD subtypes required by Matter commissioning) - Linux — Pure-Swift RFC 6762 responder over SwiftNIO; no system daemon dependency
The library is intentionally protocol-agnostic. Consumers define their own service types via ServiceType extensions:
// In matter-swift
extension ServiceType {
public static let commissionable: ServiceType = "_matterc._udp"
public static let operational: ServiceType = "_matter._tcp"
}
// In hap-swift
extension ServiceType {
public static let hapAccessory: ServiceType = "_hap._tcp"
}Add mdns-swift to your Package.swift:
dependencies: [
.package(url: "https://github.com/acumen-dev/mdns-swift.git", from: "1.0.0")
]import MDNSCore
#if canImport(Network)
import MDNSApple
let discovery: any ServiceDiscovery = AppleServiceDiscovery()
#else
import MDNSLinux
let discovery: any ServiceDiscovery = LinuxServiceDiscovery()
#endif
try await discovery.advertise(service: ServiceRecord(
name: "My Bridge",
serviceType: "_hap._tcp",
host: "",
port: 51826,
txtRecords: ["id": "AA:BB:CC:DD:EE:FF", "c#": "1"]
))for await record in discovery.browse(serviceType: "_hap._tcp") {
print("Found: \(record.name) (port \(record.port))")
}let address = try await discovery.resolve(record)
print("Connecting to \(address.host):\(address.port)")| Module | Purpose | Platforms |
|---|---|---|
| MDNSCore | ServiceDiscovery protocol, ServiceRecord, ServiceType, NetworkAddress. Zero platform dependencies. |
All |
| MDNSApple | AppleServiceDiscovery using Network.framework + dnssd. |
Apple only |
| MDNSLinux | LinuxServiceDiscovery using SwiftNIO + pure-Swift RFC 6762 codec. |
All (primary target: Linux) |
MDNSCore
↑
├── MDNSApple (Apple platforms)
└── MDNSLinux (Linux / cross-platform)
ServiceType is a RawRepresentable struct backed by the DNS-SD string (e.g. "_hap._tcp"). It conforms to ExpressibleByStringLiteral and Hashable, so consumers add typed static members via Swift extensions:
extension ServiceType {
static let myService: ServiceType = "_myservice._tcp"
}
// Both of these work:
discovery.browse(serviceType: .myService)
discovery.browse(serviceType: "_myservice._tcp")| Platform | Minimum Version |
|---|---|
| macOS | 15.0 |
| iOS | 18.0 |
| tvOS | 18.0 |
| watchOS | 11.0 |
| visionOS | 2.0 |
| Linux | Swift 6.1+ (Ubuntu 24.04 tested) |
Licensed under the Apache License, Version 2.0. See LICENSE.md for details.