2025 System Services
WWDC25 · 21 min · System Services
Use structured concurrency with Network framework
Network framework is the best way to make low-level network connections on Apple platforms — and in iOS, iPadOS, and macOS 26, it’s a perfect fit for your structured concurrency code. We’ll explore how you can make connections, send and receive data and framed messages, listen for incoming connections, and browse the network for services. We’ll also cover key best practices along the way.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 13 snippets
Make a connection with TLS
// Make a connection
import Network
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) {
TLS()
} Make a connection with TLS and IP options
// Make a connection
import Network
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029) {
TLS {
TCP {
IP()
.fragmentationEnabled(false)
}
}
} Make a connection with customized parameters
// Make a connection
import Network
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029),
using: .parameters {
TLS {
TCP {
IP()
.fragmentationEnabled(false)
}
}
}
.constrainedPathsProhibited(true)) Send and receive on a connection
// Send and receive on a connection
import Network
public func sendAndReceiveWithTLS() async throws {
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) {
TLS()
}
let outgoingData = Data("Hello, world!".utf8)
try await connection.send(outgoingData)
let incomingData = try await connection.receive(exactly: 98).content
print("Received data: \(incomingData)")
} Send and receive on a connection
// Send and receive on a connection
import Network
public func sendAndReceiveWithTLS() async throws {
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) {
TLS()
}
let outgoingData = Data("Hello, world!".utf8)
try await connection.send(outgoingData)
let remaining32 = try await connection.receive(as: UInt32.self).content
guard var remaining = Int(exactly: remaining32) else { /* ... throw an error ... */ }
while remaining > 0 {
let imageChunk = try await connection.receive(atLeast: 1, atMost: remaining).content
remaining -= imageChunk.count
// Parse the next portion of the image before continuing
}
} Tic-Tac-Toe game messages
// TicTacToe game messages
import Network
enum GameMessage: Int {
case selectedCharacter = 0
case move = 1
}
struct GameCharacter: Codable {
let character: String
}
struct GameMove: Codable {
let row: Int
let column: Int
} Send TicTacToe game messages with TLV
// Send TicTacToe game messages with TLV
import Network
public func sendWithTLV() async throws {
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) {
TLV {
TLS()
}
}
let characterData = try JSONEncoder().encode(GameCharacter(character: "🐨"))
try await connection.send(characterData, type: GameMessage.selectedCharacter.rawValue)
} Receive TicTacToe game messages with TLV
import Network
public func receiveWithTLV() async throws {
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) {
TLV {
TLS()
}
}
let (incomingData, metadata) = try await connection.receive()
switch GameMessage(rawValue: metadata.type) {
case .selectedCharacter:
let character = try JSONDecoder().decode(GameCharacter.self, from: incomingData)
print("Character selected: \(character)")
case .move:
let move = try JSONDecoder().decode(GameMove.self, from: incomingData)
print("Move: \(move)")
case .none:
print("Unknown message")
}
} Tic-Tac-Toe game messages with Coder
// TicTacToe game messages with Coder
import Network
enum GameMessage: Codable {
case selectedCharacter(String)
case move(row: Int, column: Int)
} Send TicTacToe game messages with Coder
// Send TicTacToe game messages with Coder
import Network
public func sendWithCoder() async throws {
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) {
Coder(GameMessage.self, using: .json) {
TLS()
}
}
let selectedCharacter: GameMessage = .selectedCharacter("🐨")
try await connection.send(selectedCharacter)
} Receive TicTacToe game messages with Coder
// Receive TicTacToe game messages with Coder
import Network
public func receiveWithCoder() async throws {
let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) {
Coder(GameMessage.self, using: .json) {
TLS()
}
}
let gameMessage = try await connection.receive().content
switch gameMessage {
case .selectedCharacter(let character):
print("Character selected: \(character)")
case .move(let row, let column):
print("Move: (\(row), \(column))")
}
} Listen for incoming connections with NetworkListener
// Listen for incoming connections with NetworkListener
import Network
public func listenForIncomingConnections() async throws {
try await NetworkListener {
Coder(GameMessage.self, using: .json) {
TLS()
}
}.run { connection in
for try await (gameMessage, _) in connection.messages {
// Handle the GameMessage
}
}
} Browse for nearby paired Wi-Fi Aware devices
// Browse for nearby paired Wi-Fi Aware devices
import Network
import WiFiAware
public func findNearbyDevice() async throws {
let endpoint = try await NetworkBrowser(for: .wifiAware(.connecting(to: .allPairedDevices, from: .ticTacToeService))).run { endpoints in
.finish(endpoints.first!)
}
// Make a connection to the endpoint
} Resources
Related sessions
-
28 min -
1h 2m -
24 min