Loading...
Loading...
Expert guidance on SwiftNIO best practices, patterns, and implementation. Use when developers mention: (1) SwiftNIO, NIO, ByteBuffer, Channel, ChannelPipeline, ChannelHandler, EventLoop, NIOAsyncChannel, or NIOFileSystem, (2) EventLoopFuture, ServerBootstrap, or DatagramBootstrap, (3) TCP/UDP server or client implementation, (4) ByteToMessageDecoder or wire protocol codecs, (5) binary protocol parsing or serialization, (6) blocking the event loop issues.
npx skill4agent add joannis/claude-skills swift-nioPackage.swiftEventLoopFutureNIOAsyncChannelChannelHandlerEventLoopFutureEventLoopPromiseByteBufferreferences/Channels.mdNIOAsyncChannelServerBootstrapDatagramBootstrapreferences/EventLoops.mdreferences/ByteBuffer.mdreferences/ByteToMessageCodecs.mdByteToMessageDecoderMessageToByteEncoder.get()NIOAsyncChannelNIOThreadPoolreferences/EventLoops.mdInboundOutInboundInOutboundOutOutboundInreferences/Channels.mdByteToMessageDecoderMessageToByteEncoderreadLengthPrefixedSlicewriteLengthPrefixedreferences/ByteToMessageCodecs.mdreadSlicereadBytesreferences/ByteBuffer.md.wait().get().flatMaplet server = try await ServerBootstrap(group: MultiThreadedEventLoopGroup.singleton)
.bind(host: "0.0.0.0", port: 8080) { channel in
channel.eventLoop.makeCompletedFuture {
try NIOAsyncChannel(
wrappingChannelSynchronously: channel,
configuration: .init(
inboundType: ByteBuffer.self,
outboundType: ByteBuffer.self
)
)
}
}
try await withThrowingDiscardingTaskGroup { group in
try await server.executeThenClose { clients in
for try await client in clients {
group.addTask {
try await handleClient(client)
}
}
}
}// Preferred: Use the singleton
let group = MultiThreadedEventLoopGroup.singleton
// Get any EventLoop from the group
let eventLoop = group.any()// From EventLoopFuture to async
let result = try await someFuture.get()
// From async to EventLoopFuture
let future = eventLoop.makeFutureWithTask {
try await someAsyncOperation()
}var buffer = ByteBufferAllocator().buffer(capacity: 1024)
// Writing
buffer.writeString("Hello")
buffer.writeInteger(UInt32(42))
// Reading
let string = buffer.readString(length: 5)
let number = buffer.readInteger(as: UInt32.self)EventLoops.mdChannels.mdByteToMessageCodecs.mdpatterns.mdNIOAsyncChannelMultiThreadedEventLoopGroup.singletonByteBufferDataNIOFoundationCompatimport NIOFoundationCompat
// ByteBuffer to Data
let data = Data(buffer: byteBuffer)
// Data to ByteBuffer - use writeData for better performance
var buffer = ByteBuffer()
buffer.writeData(data) // Faster than writeBytes(data)var buffer = Data()
var messageLength: UInt32?
for try await message in inbound {
buffer.append(message)
if messageLength == nil && buffer.count >= 4 {
messageLength = UInt32(buffer[0]) << 24
| UInt32(buffer[1]) << 16
| UInt32(buffer[2]) << 8
| UInt32(buffer[3])
buffer = Data(buffer.dropFirst(4)) // Copies data!
}
}var buffer = ByteBuffer()
for try await message in inbound {
buffer.writeBytes(message)
if buffer.readableBytes >= 4 {
let readerIndex = buffer.readerIndex
guard let messageLength = buffer.readInteger(endianness: .big, as: UInt32.self) else {
continue
}
if buffer.readableBytes >= messageLength {
guard let bytes = buffer.readBytes(length: Int(messageLength)) else { continue }
// Process bytes...
} else {
// Not enough data yet, reset reader index
buffer.moveReaderIndex(to: readerIndex)
}
}
}| Type | Source | Platform | Notes |
|---|---|---|---|
| stdlib | All | Safe, growable, good for Embedded Swift |
| stdlib (6.1+) | All | Fixed-size, stack-allocated, no heap allocation |
| Foundation | All (large binary) | Not always contiguous on Apple platforms |
| SwiftNIO | All (requires NIO) | Best for network protocols, not Embedded |
| stdlib (6.2+) | All | Zero-copy view, requires Swift 6.2+ |
| stdlib | All | Unsafe, manual memory management |
DataByteBuffer[UInt8]InlineArraySpan<UInt8>executeThenClosereturn try await channel.executeThenClose { inbound, outbound in
let socket = Client(inbound: inbound, outbound: outbound, channel: channel.channel)
return try await perform(client)
}AsyncSequenceAsyncIteratorDatagramBootstrapAddressedEnvelope<ByteBuffer>MulticastChannelSocketOptionValueso_reuseport