Swift (nozzle.swift)
nozzle.swift provides an idiomatic Swift wrapper over the nozzle C ABI.
Requirements
- macOS 12+
- Swift 5.9+
- Xcode 15+ (or Swift Toolchain)
- CMake 3.20+
Setup
git clone [email protected]:nozzle-io/nozzle.swift.git
cd nozzle.swift
git submodule update --init --recursive
./Scripts/bootstrap.sh
Build & Test
Sender
import Nozzle
let sender = try Sender.create(name: "my-output", applicationName: "MyApp")
let frame = try sender.acquireWritableFrame(width: 1920, height: 1080, format: .rgba8Unorm)
let pixels = try frame.lockWritablePixels()
let buffer = pixels.data.bindMemory(to: UInt8.self, capacity: pixels.byteCount)
// ... write pixel data ...
pixels.unlock()
try sender.commitFrame(frame)
Receiver
import Nozzle
let receiver = try Receiver.create(name: "my-output", applicationName: "MyViewer")
if receiver.isConnected, let info = receiver.connectedInfo {
print("Connected to \(info.name): \(info.width)x\(info.height) @ \(info.estimatedFps) FPS")
}
let frame = try receiver.acquireFrame()
let info = frame.info
print("Frame \(info.frameIndex): \(info.width)x\(info.height)")
let pixels = try frame.lockPixels()
let buffer = pixels.data.bindMemory(to: UInt8.self, capacity: pixels.byteCount)
// ... read pixel data ...
pixels.unlock()
Discovery
let senders = try Discovery.enumerateSenders()
for sender in senders {
print("\(sender.name) (\(sender.applicationName)) — \(sender.backend)")
}
Non-blocking Acquire
let frame = try receiver.acquireFrame(timeoutMs: 0)
OpenGL Interop
// Publish an existing OpenGL texture
try sender.publishGLTexture(name: glTextureName, target: .texture2D,
width: 1920, height: 1080, format: .bgra8Unorm)
// Copy a received frame to an OpenGL texture
try frame.copyToGLTexture(name: glTextureName, target: .texture2D,
width: 1920, height: 1080, format: .bgra8Unorm)
API Reference
Sender
| Method |
Description |
Sender.create(name:applicationName:ringBufferSize:allowFormatFallback:) |
Create a sender |
sender.info |
Get sender metadata |
sender.acquireWritableFrame(width:height:format:) |
Acquire a frame for writing |
sender.commitFrame(_ frame:) |
Publish a committed frame |
sender.publishGLTexture(name:target:width:height:format:) |
Publish an OpenGL texture |
Receiver
| Method |
Description |
Receiver.create(name:applicationName:receiveMode:) |
Create a receiver |
receiver.acquireFrame(timeoutMs:) |
Acquire the latest frame |
receiver.isConnected |
Check if connected to a sender |
receiver.connectedInfo |
Get connected sender details |
Frame
| Method |
Description |
frame.info |
Get frame metadata |
frame.lockPixels() |
Map frame pixels for reading |
frame.lockWritablePixels() |
Map frame pixels for writing |
frame.release() |
Explicitly release (auto-released on deinit) |
MappedPixels
| Property |
Description |
data |
Raw pointer to pixel buffer |
rowBytes |
Bytes per row |
width / height |
Dimensions |
format |
Pixel format |
byteCount |
Total buffer size |
Memory Management
Sender, Receiver, Frame, Device — reference types with deinit that call the corresponding C destroy functions
MappedPixels — auto-unlocks on deinit; explicit unlock() available
Frame.release() — safe to call multiple times (no-op after first release)
Architecture
nozzle.swift
├── Sources/CNozzle/ C modulemap → deps/nozzle/include/nozzle/nozzle_c.h
├── Sources/Nozzle/ Swift wrapper over C ABI
├── deps/nozzle/ git submodule
└── Scripts/bootstrap.sh Builds nozzle static library