-
Use a concorrência estruturada com o framework Network
O framework Network é a melhor maneira de fazer conexões de rede de baixo nível em plataformas Apple. No iOS, iPadOS e macOS 26, ele é uma ótima opção para seu código de concorrência estruturada. Vamos explorar como você pode fazer conexões, enviar e receber dados e mensagens protegidas, aceitar conexões de entrada e navegar na rede em busca de serviços. Também abordaremos as principais melhores práticas ao longo da sessão.
Capítulos
- 0:00 - Introdução
- 0:45 - Fazer conexões
- 7:22 - Enviar e receber
- 14:22 - Aceitar conexões de entrada
- 16:05 - Encontrar outros dispositivos
Recursos
Vídeos relacionados
WWDC25
WWDC18
-
Buscar neste vídeo...
-
-
4:04 - Make a connection with TLS
// Make a connection import Network let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) { TLS() } -
4:41 - 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) } } } -
5:07 - 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)) -
7:30 - 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)") } -
8:29 - 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 } } -
11:06 - 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 } -
11:24 - 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) } -
11:53 - 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") } } -
12:50 - 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) } -
13:13 - 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) } -
13:53 - 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))") } } -
15:16 - 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 } } } -
17:39 - 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 }
-
-
- 0:00 - Introdução
Saiba as novidades do framework Network. Entenda como criar conexões, enviar e receber dados, escutar conexões de entrada e descobrir pontos de extremidade na rede.
- 0:45 - Fazer conexões
O framework Network simplifica a rede de apps. Ele oferece recursos como "Connect by Name" e "Happy Eyeballs" para uma resolução de endereços. Ele tem segurança TLS integrada e suporte para transportes como o QUIC. Com o framework Network, crie uma pilha de protocolos usando uma API declarativa. O framework gerencia as transições de interfaces de rede, proxies e estados de conexão, garantindo conexões robustas e responsivas. A NetworkConnection gerencia o ciclo de vida da conexão, transitando entre estados como 'preparando', 'pronto', 'aguardando', 'falhou' ou 'cancelado'. Você pode monitorar esses estados para atualizar a interface.
- 7:22 - Enviar e receber
O envio e o recebimento de dados no framework Network são funções assíncronas que iniciam as conexões, se necessário. A função 'send' suspende a tarefa até que os dados fornecidos sejam processados. Ao receber dados usando protocolos de fluxo como TLS e TCP, o número de bytes deve ser especificado. Erros podem ocorrer durante o 'send' ou 'receive', e os erros associados fornecem explicações para as interrupções. Para cenários em que o tamanho dos dados é desconhecido, como no carregamento de imagens, use a função 'receive', com intervalos de bytes mínimo e máximo especificados. Para simplificar o manuseio de mensagens, o framework inclui um framer Type-Length-Value (TLV), que codifica e decodifica as mensagens, garantindo que o que é enviado seja exatamente o que é recebido. No iOS e macOS 26, agora é possível enviar e receber tipos Codable diretamente.
- 14:22 - Aceitar conexões de entrada
O NetworkListener permite que o app aceite conexões de entrada. É inicializado com uma pilha de protocolos e, ao chamar 'run', inicia uma nova subtarefa para cada conexão de entrada, encaminhando-as para um manipulador para o processamento assíncrono das mensagens.
- 16:05 - Encontrar outros dispositivos
No iOS 26, o framework Network apresenta o NetworkBrowser, que permite que o app descubra pontos de extremidade para conexões de rede. O NetworkBrowser pode utilizar o Wi-Fi Aware, tecnologia de rede ponto a ponto, ou o Bonjour, para encontrar dispositivos ou serviços próximos. Você pode criar um NetworkBrowser para buscar serviços usando descritores de pesquisa. O ponto de extremidade pode ser usado para inicializar uma NetworkConnection. Essas APIs, desenvolvidas para a concorrência estruturada do Swift, tornam a criação de apps de rede mais fácil e limpa, eliminando código repetitivo, além de oferecer a flexibilidade do framework Network.