Agent skills for iOS, iPadOS, Swift, SwiftUI, and modern Apple framework development.
71
89%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
Low-level networking with the Network framework. Use when you need TCP/UDP connections, WebSockets, Bonjour service discovery, local servers, or network path monitoring beyond what URLSession provides. All examples target Swift 6.3 / iOS 26+.
A bidirectional data connection between a local and remote endpoint. Supports TCP, UDP, TLS, DTLS, QUIC, and WebSocket protocols.
Documentation: sosumi.ai/documentation/network/nwconnection
import Network
let connection = NWConnection(
host: "api.example.com",
port: 443,
using: .tls
)
connection.stateUpdateHandler = { state in
switch state {
case .ready:
print("Connected")
case .waiting(let error):
print("Waiting: \(error.localizedDescription)")
case .failed(let error):
print("Failed: \(error.localizedDescription)")
case .cancelled:
print("Cancelled")
default:
break
}
}
connection.start(queue: .main)func send(_ data: Data, on connection: NWConnection) {
connection.send(
content: data,
contentContext: .defaultMessage,
isComplete: true,
completion: .contentProcessed { error in
if let error {
print("Send error: \(error)")
}
}
)
}func receive(on connection: NWConnection) {
connection.receive(
minimumIncompleteLength: 1,
maximumLength: 65536
) { content, contentContext, isComplete, error in
if let data = content {
handleData(data)
}
if isComplete {
connection.cancel()
} else if let error {
print("Receive error: \(error)")
} else {
// Continue receiving
receive(on: connection)
}
}
}let udpConnection = NWConnection(
host: "239.0.0.1",
port: 5000,
using: .udp
)
udpConnection.stateUpdateHandler = { state in
if case .ready = state {
let message = "Hello".data(using: .utf8)!
udpConnection.send(
content: message,
completion: .contentProcessed { _ in }
)
}
}
udpConnection.start(queue: .main)States flow in order: setup → preparing → ready → cancelled/failed.
A connection may enter waiting(NWError) if the network path is unavailable
and retry when connectivity returns.
Always cancel connections when done:
connection.cancel() // Releases resources, transitions to .cancelledAn object that listens for incoming network connections. Use to create local TCP/UDP servers.
Documentation: sosumi.ai/documentation/network/nwlistener
import Network
func startServer(port: UInt16) throws -> NWListener {
let listener = try NWListener(using: .tcp, on: NWEndpoint.Port(rawValue: port)!)
listener.stateUpdateHandler = { state in
switch state {
case .ready:
print("Listening on port \(listener.port?.rawValue ?? 0)")
case .failed(let error):
print("Listener failed: \(error)")
listener.cancel()
default:
break
}
}
listener.newConnectionHandler = { connection in
print("New connection from \(connection.endpoint)")
connection.stateUpdateHandler = { state in
if case .ready = state {
receive(on: connection)
}
}
connection.start(queue: .main)
}
listener.start(queue: .main)
return listener
}let listener = try NWListener(using: .tcp)
listener.service = NWListener.Service(
name: "MyApp",
type: "_myapp._tcp"
)
listener.serviceRegistrationUpdateHandler = { change in
switch change {
case .add(let endpoint):
print("Service registered: \(endpoint)")
default:
break
}
}
listener.start(queue: .main)Discovers Bonjour/mDNS services on the local network.
Documentation: sosumi.ai/documentation/network/nwbrowser
import Network
let browser = NWBrowser(
for: .bonjour(type: "_myapp._tcp", domain: nil),
using: .tcp
)
browser.stateUpdateHandler = { state in
if case .failed(let error) = state {
print("Browser failed: \(error)")
}
}
browser.browseResultsChangedHandler = { results, changes in
for result in results {
switch result.endpoint {
case .service(let name, let type, let domain, _):
print("Found: \(name).\(type)\(domain)")
default:
break
}
}
for change in changes {
switch change {
case .added(let result):
print("Added: \(result.endpoint)")
case .removed(let result):
print("Removed: \(result.endpoint)")
default:
break
}
}
}
browser.start(queue: .main)// result is an NWBrowser.Result from browseResultsChangedHandler
let connection = NWConnection(to: result.endpoint, using: .tcp)
connection.start(queue: .main)Monitors network path changes. Replaces the deprecated SCNetworkReachability
API. Use to detect connectivity changes, expensive paths (cellular), and
constrained paths (Low Data Mode).
Documentation: sosumi.ai/documentation/network/nwpathmonitor
import Network
func networkStatusStream() -> AsyncStream<NWPath> {
AsyncStream { continuation in
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
continuation.yield(path)
}
continuation.onTermination = { _ in
monitor.cancel()
}
monitor.start(queue: DispatchQueue(label: "NetworkMonitor"))
}
}
// Usage in a view model
@MainActor @Observable
class ConnectivityModel {
var isConnected = true
var isExpensive = false
var isConstrained = false
func startMonitoring() async {
for await path in networkStatusStream() {
isConnected = path.status == .satisfied
isExpensive = path.isExpensive // Cellular
isConstrained = path.isConstrained // Low Data Mode
}
}
}// Monitor only Wi-Fi
let wifiMonitor = NWPathMonitor(requiredInterfaceType: .wifi)
wifiMonitor.pathUpdateHandler = { path in
print("Wi-Fi: \(path.status)")
}
wifiMonitor.start(queue: .global())| Property | Description |
|---|---|
status | .satisfied, .unsatisfied, or .requiresConnection |
isExpensive | true on cellular or personal hotspot |
isConstrained | true when Low Data Mode is enabled |
availableInterfaces | Array of available NWInterface objects |
supportsDNS | Whether DNS resolution is available |
supportsIPv4 / supportsIPv6 | Protocol family support |
for await path in networkStatusStream() {
if path.isConstrained {
// Low Data Mode: reduce image quality, skip prefetch
imageQuality = .low
} else if path.isExpensive {
// Cellular: use standard quality, skip video preload
imageQuality = .standard
} else {
// Wi-Fi: full quality, prefetch aggressively
imageQuality = .high
}
}NWParameters defines the protocols and options for connections and listeners.
import Network
// TCP with custom options
let tcpParams = NWParameters.tcp
tcpParams.requiredInterfaceType = .wifi
tcpParams.prohibitExpensivePaths = true
tcpParams.prohibitConstrainedPaths = true
let tcpOptions = tcpParams.defaultProtocolStack
.transportProtocol as! NWProtocolTCP.Options
tcpOptions.connectionTimeout = 10
tcpOptions.enableKeepalive = true
tcpOptions.keepaliveInterval = 30
let connection = NWConnection(
host: "api.example.com",
port: 8080,
using: tcpParams
)let udpParams = NWParameters.udp
let udpOptions = udpParams.defaultProtocolStack
.transportProtocol as! NWProtocolUDP.Options
udpOptions.preferNoChecksum = true
let connection = NWConnection(
host: "239.0.0.1",
port: 5000,
using: udpParams
)Configure TLS for secure connections using NWProtocolTLS.Options.
import Network
let tlsParams = NWParameters(tls: NWProtocolTLS.Options())
// Access TLS options for customization
let tlsOptions = tlsParams.defaultProtocolStack
.applicationProtocols.first as! NWProtocolTLS.Options
sec_protocol_options_set_min_tls_protocol_version(
tlsOptions.securityProtocolOptions,
.TLSv13
)
let connection = NWConnection(
host: "secure.example.com",
port: 443,
using: tlsParams
)connection.stateUpdateHandler = { state in
if case .ready = state {
if let metadata = connection.metadata(
definition: NWProtocolTLS.definition
) as? NWProtocolTLS.Metadata {
let secMetadata = metadata.securityProtocolMetadata
let negotiatedProtocol = sec_protocol_metadata_get_negotiated_tls_protocol_version(secMetadata)
print("TLS version: \(negotiatedProtocol)")
}
}
}Network.framework supports WebSocket via NWProtocolWebSocket.
import Network
func createWebSocketConnection(url: String) -> NWConnection {
let wsOptions = NWProtocolWebSocket.Options()
wsOptions.autoReplyPing = true
let params = NWParameters.tls
params.defaultProtocolStack.applicationProtocols.insert(
wsOptions, at: 0
)
let connection = NWConnection(
host: NWEndpoint.Host(url),
port: 443,
using: params
)
return connection
}func sendWebSocketMessage(_ text: String, on connection: NWConnection) {
let metadata = NWProtocolWebSocket.Metadata(opcode: .text)
let context = NWConnection.ContentContext(
identifier: "textMessage",
metadata: [metadata]
)
let data = text.data(using: .utf8)
connection.send(
content: data,
contentContext: context,
isComplete: true,
completion: .contentProcessed { error in
if let error {
print("WebSocket send error: \(error)")
}
}
)
}func receiveWebSocketMessage(on connection: NWConnection) {
connection.receiveMessage { data, context, isComplete, error in
if let data,
let metadata = context?.protocolMetadata(
definition: NWProtocolWebSocket.definition
) as? NWProtocolWebSocket.Metadata {
switch metadata.opcode {
case .text:
let text = String(data: data, encoding: .utf8) ?? ""
print("Received text: \(text)")
case .binary:
print("Received binary: \(data.count) bytes")
case .close:
print("Connection closed")
return
default:
break
}
}
// Continue receiving
receiveWebSocketMessage(on: connection)
}
}NetworkConnection is a new Swift-native API introduced in iOS 26 that
provides a modern, type-safe alternative to NWConnection. It uses generics
over protocol stacks, supports structured concurrency patterns, and integrates
with async/await via closure-based state handlers.
Documentation: sosumi.ai/documentation/network/networkconnection
NWConnection | NetworkConnection | |
|---|---|---|
| Availability | iOS 12+ | iOS 26+ |
| Type safety | Untyped protocol stack | Generic ApplicationProtocol parameter |
| Streams | Single connection | Built-in QUIC stream multiplexing |
| State updates | stateUpdateHandler callback | onStateUpdate, onPathUpdate closures |
| Wi-Fi Aware | Not supported | wifiAware property |
| API style | Callback-based | Closure-based with Sendable support |
import Network
// Create with protocol stack parameters
let connection = NetworkConnection(
to: .hostPort(host: "api.example.com", port: 443),
using: .tls
)
connection.onStateUpdate { state in
switch state {
case .ready:
print("Connected")
case .failed(let error):
print("Failed: \(error)")
case .cancelled:
print("Cancelled")
default:
break
}
}
connection.start()NetworkConnection supports QUIC stream multiplexing natively:
// Open a new bidirectional stream
let stream = connection.openStream(directionality: .bidirectional)
// Handle inbound streams
connection.inboundStreams { stream in
// Process incoming stream
}For new iOS 26+ projects, prefer NetworkConnection over NWConnection:
ApplicationProtocol.Sendable conformance.For projects supporting iOS versions before 26, continue using NWConnection.
Both APIs coexist and NWConnection is not deprecated.
skills
accessorysetupkit
references
activitykit
references
adattributionkit
references
alarmkit
references
app-clips
app-intents
references
app-store-optimization
app-store-review
apple-on-device-ai
appmigrationkit
references
audioaccessorykit
references
authentication
references
avkit
references
background-processing
references
browserenginekit
references
callkit
references
carplay
references
cloudkit
references
contacts-framework
references
core-bluetooth
references
core-data
core-motion
references
core-nfc
references
coreml
references
cryptokit
references
cryptotokenkit
references
debugging-instruments
device-integrity
references
dockkit
references
energykit
references
eventkit
references
financekit
references
focus-engine
gamekit
references
healthkit
references
homekit
references
ios-accessibility
ios-localization
ios-networking
ios-simulator
references
mapkit
metrickit
references
musickit
references
natural-language
references
paperkit
references
passkit
references
pdfkit
references
pencilkit
references
permissionkit
references
photokit
push-notifications
realitykit
references
relevancekit
references
scenekit
references
sensorkit
references
speech-recognition
spritekit
references
storekit
swift-api-design-guidelines
swift-architecture
swift-charts
references
swift-codable
swift-concurrency
swift-formatstyle
swift-language
swift-security
references
swift-testing
swiftdata
swiftlint
swiftui-animation
swiftui-gestures
references
swiftui-layout-components
swiftui-liquid-glass
references
swiftui-patterns
swiftui-performance
swiftui-uikit-interop
swiftui-webkit
tabletopkit
references
tipkit
references
vision-framework
weatherkit
references
widgetkit
references