Swift talks to the dongle through the SDK’s own C header, imported as a module, and loads the native library at run time with the system loader — so the package has no dependencies and links nothing. For a licensing component that is the right shape: nothing sits in the path of the check that a customer could substitute for something more agreeable.
// Package.swift
.package(url: "https://github.com/AB-KeyNub/KeyNub-SDK.git", exact: "1.1.1-swift")
// then, in a target:
.product(name: "KeyNubLicDongle", package: "KeyNub-SDK")Code language: Swift (swift)
Reading a license
import KeyNubLicDongle
let ctx = try Context()
defer { ctx.close() }
let dongle = try ctx.open() // first dongle, or ctx.open(serial:)
try dongle.verifyGenuine() // throws unless genuine
let license = try dongle.withSession { s in // closed on every exit path
try s.readRecord("license")
}Code language: Swift (swift)
What you are actually protecting
A Swift application is a native binary, and a native binary is what reverse-engineering tools were built for: guard dongle.isGenuine else { exit(1) } compiles to one conditional branch, and patching one of those in a release build is a beginner exercise. Obfuscation and hardening only raise the effort.
What cannot be patched away is data the program needs and only the dongle can decrypt. Seal it once with a developer dongle, ship only the sealed form, and the program has no copy to fall back on:
// Weak -- one patched branch.
guard dongle.isGenuine else { exit(1) }
// Strong -- the parameters only exist with the dongle present.
let parameters = try session.appDecrypt(sealedBlobShippedWithTheApp)Code language: Swift (swift)
withSession closes the session even when an error is thrown inside it, so there is no cleanup path to forget. Failures are LicenseDongleError values with a status (.noDevice, .notGenuine, .authRequired, …), so a catch branches on what happened.
Shipping the native library with a Swift application
The KeyNubLicDongle package (Swift Package Index, the SDK repository itself) loads the core library at run time, so nothing is linked and no build settings change. In a clone it finds natives/<platform>/ on its own; a shipped macOS application copies libkeynub_licdongle.dylib (a universal binary for Intel and Apple silicon) into the bundle and names it with Library.path, for example from Bundle.main.privateFrameworksPath.
On Linux the same package loads libkeynub_licdongle.so. Sandboxed Mac App Store builds need the USB entitlement to reach the device. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.
Questions Swift developers ask
Which Swift versions and platforms does the binding support?
Swift 5.9 tools and later, macOS 12 and later, and Linux. The package has no dependencies.
Can a Mac app be protected with a hardware dongle?
Yes. The dongle is a HID device that macOS handles without a kernel extension, the library is a universal binary in the bundle, and the check follows the same data-gating pattern as everywhere else: seal what the app needs, decrypt through the dongle.
Does a Swift application need administrator rights to talk to the dongle?
No, and no driver either: the dongle is a USB HID device that the operating systems handle with their built-in class drivers. On Linux, install the shipped udev rule once so that ordinary users may open it; without the rule the SDK reports access denied and names the cause in its error detail.
Does a Swift license check need an internet connection?
No. Verification is a local exchange between your program and the dongle over USB: the SDK checks the dongle’s certificate chain to KeyNub’s root and runs a live challenge-response. There is no activation server and no account, so the check works on air-gapped machines.
Who can read the license records on a dongle?
Anyone holding the dongle: a program opens a session and reads records, and can decrypt data sealed for that dongle. Writing records, erasing them and incrementing counters need your write key. What the dongle guarantees is that none of it is available without the dongle present.
Can a license written from Swift be read by a program in another language?
Yes. Every binding drives the same core library and the same dongle, and records and sealed data are language-neutral bytes. Your issuing tool can be written in one language and your product in another.
Code
Runnable sample: swift/Sources/verify_and_read/main.swift. Binding source: bindings/swift. Both are Apache-2.0, in the public SDK repository; the prebuilt native libraries are in the repository’s natives/ folder, one per platform.
All supported languages · All industries · Buy a KeyNub · Ask us something