### Install NWWebSocket via CocoaPods Source: https://github.com/pusher/nwwebsocket/blob/main/docs/index.html Instructions for integrating NWWebSocket into an Xcode project using CocoaPods. This involves adding the pod to the `Podfile` and running `pod install`. It also includes commands for updating the local pod repository and cleaning the cache if the latest version is not installed. ```ruby source 'https://github.com/CocoaPods/Specs.git' platform :ios, '14.0' use_frameworks! pod 'NWWebSocket', '~> 0.5.2' ``` -------------------------------- ### NWWebSocket Client Usage Example in Swift Source: https://context7.com/pusher/nwwebsocket/llms.txt This Swift code provides a usage example for the NWWebSocket client. It demonstrates connecting to a WebSocket, sending messages at specified intervals, and disconnecting. The example utilizes `DispatchQueue.main.asyncAfter` for delayed execution and assumes a `ChatClient` class is defined elsewhere. ```swift // Usage example let chatClient = ChatClient(username: "Alice") chatClient.connect() // Send messages DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { chatClient.sendMessage(text: "Hello everyone!") } DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { chatClient.sendMessage(text: "How is everyone doing?") } // Disconnect after some time DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) { chatClient.disconnect() } ``` -------------------------------- ### Install NWWebSocket with CocoaPods Source: https://github.com/pusher/nwwebsocket/blob/main/README.md Integrates NWWebSocket into an Xcode project using CocoaPods by specifying the dependency in the Podfile. Ensures the latest version is used by cleaning the cache and updating the repository. ```ruby source 'https://github.com/CocoaPods/Specs.git' platform :ios, '14.0' use_frameworks! pod 'NWWebSocket', '~> 0.5.9' ``` -------------------------------- ### Listen for WebSocket Messages Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Classes/NWWebSocket.html Starts listening for incoming messages on the WebSocket. This method should be called after establishing a connection. ```Swift public func listen() ``` -------------------------------- ### Add NWWebSocket Dependency via CocoaPods (Podfile) Source: https://github.com/pusher/nwwebsocket/blob/main/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/index.html Integrates NWWebSocket into an Xcode project using CocoaPods. This involves adding the `NWWebSocket` pod to the `Podfile` and running `pod install`. Ensure the CocoaPods gem is installed and the pod repository is up-to-date. ```ruby source 'https://github.com/CocoaPods/Specs.git' platform :ios, '14.0' use_frameworks! pod 'NWWebSocket', '~> 0.5.2' ``` -------------------------------- ### Configure WebSocket with Custom Options and Queue (Swift) Source: https://context7.com/pusher/nwwebsocket/llms.txt This snippet illustrates setting up a WebSocket connection with custom NWProtocolWebSocket.Options, such as enabling automatic ping replies and defining a maximum message size. It also shows how to assign a specific dispatch queue for managing connection events. ```swift import Network import NWWebSocket class AdvancedConnectionManager: WebSocketConnectionDelegate { var socket: NWWebSocket? func setupWithCustomOptions() { let url = URL(string: "wss://api.example.com/ws")! // Custom WebSocket options let options = NWProtocolWebSocket.Options() options.autoReplyPing = true // Automatically respond to pings options.maximumMessageSize = 1024 * 1024 // 1MB max message size // Custom dispatch queue for connection events let connectionQueue = DispatchQueue(label: "com.example.websocket", qos: .userInitiated) socket = NWWebSocket( url: url, connectAutomatically: false, options: options, connectionQueue: connectionQueue ) socket?.delegate = self socket?.connect() } // ... other delegate methods func webSocketDidConnect(connection: WebSocketConnection) { print("Connected with custom configuration") } func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) { print("Connection error: (error)") if case .posix(let code) = error { print("POSIX error code: (code)") } } func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) {} func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) {} func webSocketDidAttemptBetterPathMigration(result: Result) {} func webSocketDidReceivePong(connection: WebSocketConnection) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {} } ``` -------------------------------- ### Handle Network Migration with NWWebSocket in Swift Source: https://context7.com/pusher/nwwebsocket/llms.txt This Swift code demonstrates how to set up and manage a WebSocket connection using NWWebSocket, specifically handling network viability changes and automatic path migration between cellular and Wi-Fi. It includes delegate methods for connection status, network viability, and migration success or failure. Dependencies include the Network and NWWebSocket frameworks. ```swift import Network import NWWebSocket class NetworkMigrationHandler: WebSocketConnectionDelegate { var socket: NWWebSocket? func setupSocket() { let socketURL = URL(string: "wss://api.example.com/stream")! socket = NWWebSocket(url: socketURL, connectAutomatically: true) socket?.delegate = self } func webSocketDidConnect(connection: WebSocketConnection) { print("WebSocket connected") } func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) { // Called when network conditions change if isViable { print("✓ Network connection is viable") print("Connection can send and receive data") } else { print("⚠️ Network connection is not viable") print("Device may be out of range or network unavailable") // Consider implementing reconnection logic } } func webSocketDidAttemptBetterPathMigration(result: Result) { // Called when device switches between network interfaces // Example: Cellular -> Wi-Fi or Wi-Fi -> Cellular switch result { case .success(let connection): print("✓ Successfully migrated to better network path") print("Connection migrated seamlessly") // Connection object is still valid, no action needed // All subscriptions and state are preserved case .failure(let error): print("✗ Failed to migrate to better network path") print("Error: (error)") // Handle migration failure if case .posix(let code) = error { switch code { case .ENETDOWN: print("Network is down") case .ECONNABORTED: print("Connection aborted") case .ETIMEDOUT: print("Migration timed out") default: print("POSIX error: (code)") } } // Consider reconnecting DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { self?.socket?.connect() } } } func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) { print("WebSocket error: (error)") } // Implement other required delegate methods... func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) {} func webSocketDidReceivePong(connection: WebSocketConnection) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {} } ``` -------------------------------- ### Connect to WebSocket Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Classes/NWWebSocket.html Establishes a connection to the WebSocket server. This is the initial step before any communication can occur. ```Swift open func connect() ``` -------------------------------- ### Create WebSocket Connection (Manual) Source: https://context7.com/pusher/nwwebsocket/llms.txt Initializes a NWWebSocket instance and manually controls its connection lifecycle. This method is suitable when you need explicit control over when the WebSocket connects. It requires the Network and NWWebSocket frameworks and expects a URL string for the WebSocket endpoint. ```swift import Network import NWWebSocket class WebSocketManager: WebSocketConnectionDelegate { var socket: NWWebSocket? func setupWebSocket() { // Create WebSocket with manual connection let socketURL = URL(string: "wss://echo.websocket.org")! socket = NWWebSocket(url: socketURL) socket?.delegate = self // Manually trigger connection socket?.connect() } func webSocketDidConnect(connection: WebSocketConnection) { print("WebSocket connected successfully") } func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) { print("WebSocket disconnected with code: (closeCode)") if let reason = reason, let reasonString = String(data: reason, encoding: .utf8) { print("Disconnect reason: (reasonString)") } } func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) { print("WebSocket viability changed: (isViable)") } func webSocketDidAttemptBetterPathMigration(result: Result) { switch result { case .success: print("Successfully migrated to better network path") case .failure(let error): print("Failed to migrate: (error)") } } func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) { print("WebSocket error: (error)") } func webSocketDidReceivePong(connection: WebSocketConnection) { print("Received pong from server") } func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) { print("Received string message: (string)") } func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) { print("Received binary data: (data.count) bytes") } } ``` -------------------------------- ### NWWebSocket Initialization Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Classes/NWWebSocket.html Initializes a NWWebSocket instance to establish a WebSocket connection. ```APIDOC ## NWWebSocket Initialization ### Description Initializes a NWWebSocket instance which connects to a socket URL with some configuration options. ### Method `init(request:connectAutomatically:options:connectionQueue:)` ### Endpoint N/A (Client-side initialization) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift let request = URLRequest(url: URL(string: "ws://example.com")!) let websocket = NWWebSocket(request: request, connectAutomatically: true) ``` ### Response #### Success Response N/A (Initializes a WebSocket client) #### Response Example N/A --- ### Description Initializes a NWWebSocket instance which connects a socket URL with some configuration options. ### Method `init(url:connectAutomatically:options:connectionQueue:)` ### Endpoint N/A (Client-side initialization) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift let url = URL(string: "ws://example.com")! let websocket = NWWebSocket(url: url, connectAutomatically: true) ``` ### Response #### Success Response N/A (Initializes a WebSocket client) #### Response Example N/A ``` -------------------------------- ### WebSocketConnection - connect() Source: https://github.com/pusher/nwwebsocket/blob/main/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/Classes/NWWebSocket.html Initiates a connection to the WebSocket server. ```APIDOC ## POST /pusher/nwwebsocket/connect ### Description Connect to the WebSocket. ### Method POST ### Endpoint /pusher/nwwebsocket/connect ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```json { "example": "No request body needed for connect." } ``` ### Response #### Success Response (200) - **status** (string) - Indicates successful connection. #### Response Example ```json { "status": "connected" } ``` ``` -------------------------------- ### Configure WebSocket with URLRequest and Custom Headers (Swift) Source: https://context7.com/pusher/nwwebsocket/llms.txt This snippet demonstrates how to create a WebSocket connection using URLRequest, allowing for the addition of custom HTTP headers and setting a connection timeout. This is useful for authentication (e.g., Bearer tokens) and passing client-specific information. ```swift import Network import NWWebSocket class AdvancedConnectionManager: WebSocketConnectionDelegate { var socket: NWWebSocket? func setupWithCustomHeaders() { // Create URLRequest for custom configuration let url = URL(string: "wss://api.example.com/ws")! var request = URLRequest(url: url) // Add custom headers request.addValue("Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", forHTTPHeaderField: "Authorization") request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("my-client/1.0", forHTTPHeaderField: "User-Agent") request.addValue("v1", forHTTPHeaderField: "API-Version") // Set timeout request.timeoutInterval = 30.0 // Create WebSocket with URLRequest socket = NWWebSocket(request: request, connectAutomatically: true) socket?.delegate = self } // ... other delegate methods func webSocketDidConnect(connection: WebSocketConnection) { print("Connected with custom configuration") } func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) { print("Connection error: (error)") if case .posix(let code) = error { print("POSIX error code: (code)") } } func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) {} func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) {} func webSocketDidAttemptBetterPathMigration(result: Result) {} func webSocketDidReceivePong(connection: WebSocketConnection) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {} } ``` -------------------------------- ### Initialize NWWebSocket with URL Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Classes/NWWebSocket.html Initializes an NWWebSocket instance using a URL. Supports automatic connection, custom options, and a dedicated connection queue. The default options handle Ping messages automatically. ```swift public init(url: URL, connectAutomatically: Bool = false, options: NWProtocolWebSocket.Options = NWWebSocket.defaultOptions, connectionQueue: DispatchQueue = .main) ``` -------------------------------- ### Initialize NWWebSocket with URLRequest Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Classes/NWWebSocket.html Initializes an NWWebSocket instance using a URLRequest. Allows for automatic connection, custom options, and specifying a connection queue. The default options automatically reply to Ping messages. ```swift public convenience init(request: URLRequest, connectAutomatically: Bool = false, options: NWProtocolWebSocket.Options = NWWebSocket.defaultOptions, connectionQueue: DispatchQueue = .main) ``` -------------------------------- ### Sending Binary Data with NWWebSocket Source: https://context7.com/pusher/nwwebsocket/llms.txt Illustrates sending binary data messages, including raw byte arrays, image data, custom protocols, and encoded structs, over a WebSocket connection. This requires the Network, NWWebSocket, and Foundation frameworks. ```swift import Network import NWWebSocket import Foundation class BinaryDataSender: WebSocketConnectionDelegate { var socket: NWWebSocket? func setupAndSendBinary() { let socketURL = URL(string: "wss://api.example.com/upload")! socket = NWWebSocket(url: socketURL, connectAutomatically: true) socket?.delegate = self } func sendBinaryData() { // Send raw byte array let bytes: [UInt8] = [0x48, 0x65, 0x6C, 0x6C, 0x6F] // "Hello" in bytes let data = Data(bytes) socket?.send(data: data) // Send image data if let imageData = UIImage(named: "profile")?.pngData() { socket?.send(data: imageData) } // Send custom binary protocol var protocolData = Data() protocolData.append(contentsOf: [0x01, 0x02]) // Header protocolData.append(contentsOf: "payload".utf8) // Payload socket?.send(data: protocolData) // Send encoded struct struct Message: Codable { let id: Int let content: String } let message = Message(id: 123, content: "Binary message") if let encoded = try? JSONEncoder().encode(message) { socket?.send(data: encoded) } } func webSocketDidConnect(connection: WebSocketConnection) { sendBinaryData() } func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) { print("Received binary data: \(data.count) bytes") // Handle binary response if let decoded = try? JSONDecoder().decode(Response.self, from: data) { print("Decoded response: \(decoded)") } } struct Response: Codable { let status: String let id: Int } // Implement other required delegate methods... func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) {} func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) {} func webSocketDidAttemptBetterPathMigration(result: Result) {} func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) {} func webSocketDidReceivePong(connection: WebSocketConnection) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {} } ``` -------------------------------- ### Connect and Disconnect WebSocket (Swift) Source: https://github.com/pusher/nwwebsocket/blob/main/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/index.html Demonstrates how to manually connect to and disconnect from a WebSocket using NWWebSocket. Requires the NWWebSocket library and setting a delegate for handling events. The connection can be made automatic by setting `connectAutomatically` to true. ```swift let socketURL = URL(string: "wss://somewebsockethost.com") let socket = NWWebSocket(url: socketURL) socket.delegate = self socket.connect() // Use the WebSocket... socket.disconnect() ``` -------------------------------- ### Create WebSocket Connection (Automatic) Source: https://context7.com/pusher/nwwebsocket/llms.txt Initializes a NWWebSocket instance that automatically attempts to connect upon creation. This is useful for scenarios where immediate real-time communication is desired. The function requires the Network and NWWebSocket frameworks and takes a URL string and a boolean flag for automatic connection. ```swift import Network import NWWebSocket class AutoConnectManager: WebSocketConnectionDelegate { var socket: NWWebSocket? func setupAutoConnectWebSocket() { // WebSocket connects immediately when connectAutomatically is true let socketURL = URL(string: "wss://stream.example.com/live")! socket = NWWebSocket(url: socketURL, connectAutomatically: true) socket?.delegate = self // No need to call connect() - already connecting } func webSocketDidConnect(connection: WebSocketConnection) { print("Auto-connected to WebSocket") // Start sending data immediately socket?.send(string: "Hello from auto-connect!") } func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) { print("Auto-connect WebSocket disconnected") } func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) {} func webSocketDidAttemptBetterPathMigration(result: Result) {} func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) {} func webSocketDidReceivePong(connection: WebSocketConnection) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {} } ``` -------------------------------- ### Manual WebSocket Connection and Disconnection in Swift Source: https://github.com/pusher/nwwebsocket/blob/main/docs/index.html Demonstrates how to manually establish and terminate a WebSocket connection using NWWebSocket. It requires a URL for the WebSocket endpoint and optionally a delegate for handling events. The `connectAutomatically` property can be set to `true` for automatic connection upon instantiation. ```swift let socketURL = URL(string: "wss://somewebsockethost.com") let socket = NWWebSocket(url: socketURL) socket.delegate = self socket.connect() // Use the WebSocket... socket.disconnect() ``` -------------------------------- ### Send String and Binary Data over WebSocket in Swift Source: https://github.com/pusher/nwwebsocket/blob/main/README.md Demonstrates sending both UTF-8 encoded strings and raw binary data over an established WebSocket connection using NWWebSocket's `send` methods. ```swift // Sending a `String` let message = "Hello, world!" socket.send(string: message) // Sending some binary data let data: [UInt8] = [123, 234] let messageData = Data(data) socket.send(data: messageData) ``` -------------------------------- ### Send One-Time Ping with NWWebSocket (Swift) Source: https://context7.com/pusher/nwwebsocket/llms.txt This Swift code demonstrates how to send a single ping to a WebSocket connection to verify its liveness. It requires the Network and NWWebSocket frameworks. The function `checkConnection` sends the ping, and the `webSocketDidReceivePong` delegate method confirms a successful response. ```swift import Network import NWWebSocket class PingManager: WebSocketConnectionDelegate { var socket: NWWebSocket?n func setupPing() { let socketURL = URL(string: "wss://api.example.com/ws")! socket = NWWebSocket(url: socketURL, connectAutomatically: true) socket?.delegate = self } func checkConnection() { // Send single ping to verify connection is alive socket?.ping() print("Ping sent, waiting for pong...") } func webSocketDidConnect(connection: WebSocketConnection) { print("Connected, sending ping in 2 seconds...") DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { [weak self] in self?.checkConnection() } } func webSocketDidReceivePong(connection: WebSocketConnection) { print("✓ Pong received - connection is alive!") let timestamp = Date() print("Pong received at: (timestamp)") } // Implement other required delegate methods... func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) { print("Disconnected") } func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) {} func webSocketDidAttemptBetterPathMigration(result: Result) {} func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {} } ``` -------------------------------- ### Add NWWebSocket as a Dependency in Package.swift Source: https://github.com/pusher/nwwebsocket/blob/main/docs/index.html Shows how to add NWWebSocket as a dependency to a Swift Package Manager project. This is done by specifying the package repository URL and version in the `Package.swift` file. It also indicates the necessary import statements for using the library in source files. ```swift // swift-tools-version:5.1 import PackageDescription let package = Package( name: "YourPackage", products: [ .library( name: "YourPackage", targets: ["YourPackage"]), ], dependencies: [ .package(url: "https://github.com/pusher/NWWebSocket.git", .upToNextMajor(from: "0.5.2")), ], targets: [ .target( name: "YourPackage", dependencies: ["NWWebSocket"]) ] ) ``` -------------------------------- ### Define WebSocket Connection Protocol in Swift Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Protocols.html Defines the essential methods and properties for establishing and managing a WebSocket connection. This protocol serves as the blueprint for any object that needs to handle WebSocket communication within the NWWebSocket framework. It does not have external dependencies beyond Swift's standard library. ```swift public protocol WebSocketConnection ``` -------------------------------- ### WebSocketConnectionDelegate Methods Source: https://github.com/pusher/nwwebsocket/blob/main/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/Protocols/WebSocketConnectionDelegate.html This section covers the methods defined by the WebSocketConnectionDelegate protocol, which are callbacks for different WebSocket connection states and events. ```APIDOC ## WebSocketConnectionDelegate Methods ### Description Methods defined by the `WebSocketConnectionDelegate` protocol to handle WebSocket connection events. ### Protocol `WebSocketConnectionDelegate` ### Methods #### `webSocketDidConnect(connection:)` ##### Description Tells the delegate that the WebSocket did connect successfully. ##### Declaration ```swift func webSocketDidConnect(connection: WebSocketConnection) ``` ##### Parameters - **connection** (WebSocketConnection) - Required - The active `WebSocketConnection`. #### `webSocketDidDisconnect(connection:closeCode:reason:)` ##### Description Tells the delegate that the WebSocket did disconnect. ##### Declaration ```swift func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) ``` ##### Parameters - **connection** (WebSocketConnection) - Required - The `WebSocketConnection` that disconnected. - **closeCode** (NWProtocolWebSocket.CloseCode) - Required - A `NWProtocolWebSocket.CloseCode` describing how the connection closed. - **reason** (Data?) - Optional - Optional extra information explaining the disconnection. (Formatted as UTF-8 encoded `Data`). #### `webSocketViabilityDidChange(connection:isViable:)` ##### Description Tells the delegate that the WebSocket connection viability has changed. An example scenario of when this method would be called is a Wi-Fi connection being lost due to a device moving out of signal range, and then the method would be called again once the device moved back in range. ##### Declaration ```swift func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) ``` ##### Parameters - **connection** (WebSocketConnection) - Required - The `WebSocketConnection` whose viability has changed. - **isViable** (Bool) - Required - A `Bool` indicating if the connection is viable or not. #### `webSocketDidAttemptBetterPathMigration(result:)` ##### Description Tells the delegate that the WebSocket has attempted a migration based on a better network path becoming available. An example of when this method would be called is if a device is using a cellular connection, and a Wi-Fi connection becomes available. This method will also be called if a device loses a Wi-Fi connection, and a cellular connection is available. ##### Declaration ```swift func webSocketDidAttemptBetterPathMigration(result: Result) ``` ##### Parameters - **result** (Result) - Required - A `Result` containing the `WebSocketConnection` if the migration was successful, or a `NWError` if the migration failed for some reason. #### `webSocketDidReceiveError(connection:error:)` ##### Description Tells the delegate that the WebSocket received an error. An error received by a WebSocket is not necessarily fatal. ##### Declaration ```swift func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) ``` ##### Parameters - **connection** (WebSocketConnection) - Required - The `WebSocketConnection` that received the error. - **error** (NWError) - Required - The `NWError` that was received. ``` -------------------------------- ### Sending String Messages with NWWebSocket Source: https://context7.com/pusher/nwwebsocket/llms.txt Demonstrates sending UTF-8 encoded string messages, including plain text, JSON, and formatted strings, over a WebSocket connection. This requires the Network and NWWebSocket frameworks. ```swift import Network import NWWebSocket class MessageSender { var socket: NWWebSocket? func sendTextMessages() { let socketURL = URL(string: "wss://api.example.com/chat")! socket = NWWebSocket(url: socketURL, connectAutomatically: true) socket?.delegate = self } func sendChatMessage(message: String, user: String) { // Send simple string socket?.send(string: "Hello, world!") // Send JSON string let jsonMessage = """ { "type": "chat", "user": "\(user)", "message": "\(message)", "timestamp": \(Date().timeIntervalSince1970) } """ socket?.send(string: jsonMessage) // Send formatted data let notification = "User \(user) has joined the chat" socket?.send(string: notification) } } extension MessageSender: WebSocketConnectionDelegate { func webSocketDidConnect(connection: WebSocketConnection) { sendChatMessage(message: "Hey everyone!", user: "Alice") } func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) { print("Server response: \(string)") } // Implement other required delegate methods... func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) {} func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) {} func webSocketDidAttemptBetterPathMigration(result: Result) {} func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) {} func webSocketDidReceivePong(connection: WebSocketConnection) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {} } ``` -------------------------------- ### NWWebSocket Default Options Property Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Classes/NWWebSocket.html Provides the default Network Protocol WebSocket Options for establishing a connection. These options are pre-configured to automatically respond to Ping messages, simplifying client implementation. ```swift public static var defaultOptions: NWProtocolWebSocket.Options { get } ``` -------------------------------- ### Handle WebSocket Connection Events with Swift Delegate Source: https://github.com/pusher/nwwebsocket/blob/main/README.md Implement the WebSocketConnectionDelegate protocol in Swift to manage various connection events. This includes responding to successful connections, disconnections, viability changes, path migrations, errors, and received pong messages. ```swift extension MyWebSocketConnectionManager: WebSocketConnectionDelegate { func webSocketDidConnect(connection: WebSocketConnection) { // Respond to a WebSocket connection event } func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) { // Respond to a WebSocket disconnection event } func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) { // Respond to a WebSocket connection viability change event } func webSocketDidAttemptBetterPathMigration(result: Result) { // Respond to when a WebSocket connection migrates to a better network path // (e.g. A device moves from a cellular connection to a Wi-Fi connection) } func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) { // Respond to a WebSocket error event } func webSocketDidReceivePong(connection: WebSocketConnection) { // Respond to a WebSocket connection receiving a Pong from the peer } func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) { // Respond to a WebSocket connection receiving a `String` message } func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) { // Respond to a WebSocket connection receiving a binary `Data` message } } ``` -------------------------------- ### Connect WebSocket automatically in Swift Source: https://github.com/pusher/nwwebsocket/blob/main/README.md Configures NWWebSocket to automatically connect upon initialization by setting `connectAutomatically` to `true`. Disconnection is still handled manually. ```swift let socketURL = URL(string: "wss://somewebsockethost.com") let socket = NWWebSocket(url: socketURL, connectAutomatically: true) socket.delegate = self // Use the WebSocket… socket.disconnect() ``` -------------------------------- ### Disconnecting WebSocket with Custom Close Codes in Swift Source: https://context7.com/pusher/nwwebsocket/llms.txt Demonstrates how to disconnect a WebSocket connection using the NWWebSocket library in Swift. It covers both normal disconnections and disconnections with specific close codes like `.goingAway` or `.protocolError`. This is useful for signaling the reason for disconnection to the server or client. ```swift import Network import NWWebSocket class DisconnectionManager: WebSocketConnectionDelegate { var socket: NWWebSocket? func setupSocket() { let socketURL = URL(string: "wss://api.example.com/ws")! socket = NWWebSocket(url: socketURL, connectAutomatically: true) socket?.delegate = self } func disconnectNormally() { // Normal disconnection (default close code) socket?.disconnect() print("Initiating normal disconnection...") } func disconnectWithCustomCode() { // Disconnect with specific close code - going away socket?.disconnect(closeCode: .protocolCode(.goingAway)) // Other close code examples: // socket?.disconnect(closeCode: .protocolCode(.protocolError)) // socket?.disconnect(closeCode: .protocolCode(.unsupportedData)) // socket?.disconnect(closeCode: .protocolCode(.abnormalClosure)) // socket?.disconnect(closeCode: .protocolCode(.invalidFramePayloadData)) // socket?.disconnect(closeCode: .protocolCode(.policyViolation)) // socket?.disconnect(closeCode: .protocolCode(.messageTooBig)) // socket?.disconnect(closeCode: .protocolCode(.mandatoryExtensionMissing)) // socket?.disconnect(closeCode: .protocolCode(.internalServerError)) // socket?.disconnect(closeCode: .protocolCode(.tlsHandshakeFailure)) } func webSocketDidConnect(connection: WebSocketConnection) { print("Connected") // Disconnect after 5 seconds DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { self.disconnectNormally() } } func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) { print("Disconnected with code: \(closeCode)") if let reason = reason, let reasonString = String(data: reason, encoding: .utf8) { print("Reason: \(reasonString)") } // Handle specific close codes switch closeCode { case .protocolCode(.normalClosure): print("Clean disconnection") case .protocolCode(.goingAway): print("Client/server going away") case .protocolCode(.protocolError): print("Protocol error occurred") default: print("Other close code: \(closeCode)") } } // Implement other required delegate methods... func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) {} func webSocketDidAttemptBetterPathMigration(result: Result) {} func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) {} func webSocketDidReceivePong(connection: WebSocketConnection) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {} } ``` -------------------------------- ### Swift Chat Client with NWWebSocket Source: https://context7.com/pusher/nwwebsocket/llms.txt Implements a chat client using NWWebSocket for real-time messaging. It handles connection, sending messages, receiving messages, typing indicators, and automatic reconnection. Dependencies include Network and Foundation frameworks. ```swift import Network import NWWebSocket import Foundation class ChatClient: WebSocketConnectionDelegate { private var socket: NWWebSocket? private let serverURL = "wss://chat.example.com/ws" private var username: String private var isReconnecting = false init(username: String) { self.username = username } func connect() { guard let url = URL(string: serverURL) else { return } var request = URLRequest(url: url) request.addValue(username, forHTTPHeaderField: "X-Username") request.addValue("Bearer auth_token_here", forHTTPHeaderField: "Authorization") let options = NWProtocolWebSocket.Options() options.autoReplyPing = true socket = NWWebSocket(request: request, connectAutomatically: true, options: options) socket?.delegate = self } func sendMessage(text: String) { let message: [String: Any] = [ "type": "message", "user": username, "text": text, "timestamp": Date().timeIntervalSince1970 ] if let jsonData = try? JSONSerialization.data(withJSONObject: message), let jsonString = String(data: jsonData, encoding: .utf8) { socket?.send(string: jsonString) print("Sent: \(text)") } } func sendTypingIndicator() { let typing: [String: Any] = ["type": "typing", "user": username] if let jsonData = try? JSONSerialization.data(withJSONObject: typing), let jsonString = String(data: jsonData, encoding: .utf8) { socket?.send(string: jsonString) } } func disconnect() { socket?.disconnect(closeCode: .protocolCode(.normalClosure)) } // MARK: - WebSocketConnectionDelegate func webSocketDidConnect(connection: WebSocketConnection) { print("✓ Connected to chat server") isReconnecting = false // Send join message let joinMessage: [String: Any] = ["type": "join", "user": username] if let jsonData = try? JSONSerialization.data(withJSONObject: joinMessage), let jsonString = String(data: jsonData, encoding: .utf8) { socket?.send(string: jsonString) } // Start heartbeat socket?.ping(interval: 30.0) } func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) { print("Disconnected from chat server") if let reason = reason, let reasonString = String(data: reason, encoding: .utf8) { print("Reason: \(reasonString)") } // Auto-reconnect logic if !isReconnecting && closeCode != .protocolCode(.normalClosure) { isReconnecting = true print("Attempting to reconnect in 3 seconds...") DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { [weak self] in self?.connect() } } } func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) { if isViable { print("Network connection restored") } else { print("Network connection lost - messages may not be delivered") } } func webSocketDidAttemptBetterPathMigration(result: Result) { switch result { case .success: print("Migrated to better network (e.g., Wi-Fi)") case .failure(let error): print("Migration failed: \(error)") } } func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) { print("Error: \(error)") // Log specific error types if case .posix(let code) = error { switch code { case .ECONNREFUSED: print("Connection refused - server may be down") case .ETIMEDOUT: print("Connection timed out") case .ENETUNREACH: print("Network unreachable") default: print("POSIX error: \(code)") } } } func webSocketDidReceivePong(connection: WebSocketConnection) { // Connection is alive } func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) { guard let data = string.data(using: .utf8), let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any], let type = json["type"] as? String else { return } switch type { case "message": if let user = json["user"] as? String, let text = json["text"] as? String { print("[\(user)]: \(text)") } case "join": // Handle join message if let user = json["user"] as? String { print("\(user) joined the chat.") } case "typing": // Handle typing indicator if let user = json["user"] as? String { print("\(user) is typing...") } default: print("Received unknown message type: \(type)") } } } ``` -------------------------------- ### Handle WebSocket Message Types in Swift Source: https://context7.com/pusher/nwwebsocket/llms.txt This Swift code snippet demonstrates how to process different message types received over a WebSocket connection. It handles join, leave, and typing events, printing user actions to the console. It also includes a fallback for unknown message types. This requires a `WebSocketConnection` object and a JSON dictionary as input. ```swift if let user = json["user"] as? String { print("* \(user) joined the chat") } case "leave": if let user = json["user"] as? String { print("* \(user) left the chat") } case "typing": if let user = json["user"] as? String { print("* \(user) is typing...") } default: print("Unknown message type: \(type)") } } func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) { print("Received binary data: (data.count) bytes") } } ``` -------------------------------- ### Connect and disconnect WebSocket manually in Swift Source: https://github.com/pusher/nwwebsocket/blob/main/README.md Manually establishes and terminates a WebSocket connection using NWWebSocket. Requires the conforming object to implement the `WebSocketConnectionDelegate` protocol. ```swift let socketURL = URL(string: "wss://somewebsockethost.com") let socket = NWWebSocket(url: socketURL) socket.delegate = self socket.connect() // Use the WebSocket… socket.disconnect() ``` -------------------------------- ### WebSocketConnection - send(string:) Source: https://github.com/pusher/nwwebsocket/blob/main/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/Classes/NWWebSocket.html Sends a UTF-8 formatted string over the WebSocket connection. ```APIDOC ## POST /pusher/nwwebsocket/send/string ### Description Send a UTF-8 formatted `String` over the WebSocket. ### Method POST ### Endpoint /pusher/nwwebsocket/send/string ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **message** (string) - Required - The `String` that will be sent. ### Request Example ```json { "message": "Hello, WebSocket!" } ``` ### Response #### Success Response (200) - **status** (string) - Indicates the message was sent successfully. #### Response Example ```json { "status": "message sent" } ``` ``` -------------------------------- ### NWWebSocket Public Properties Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Classes/NWWebSocket.html Provides access to the delegate and default WebSocket options. ```APIDOC ## NWWebSocket Public Properties ### Description Provides access to the delegate and default WebSocket options for the NWWebSocket class. ### Properties * **delegate** (`WebSocketConnectionDelegate?`) * Description: The WebSocket connection delegate. * Access: `weak var` * **defaultOptions** (`NWProtocolWebSocket.Options`) * Description: The default `NWProtocolWebSocket.Options` for a WebSocket connection. These options specify that the connection automatically replies to Ping messages instead of delivering them to the `receiveMessage(data:context:)` method. * Access: `public static var` ``` -------------------------------- ### Define WebSocket Connection Delegate Protocol in Swift Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Protocols.html Defines the delegate protocol for handling events and callbacks related to a WebSocket connection. Conforming types can implement these methods to respond to connection status changes, received messages, and errors. This protocol is designed to be used with reference types, indicated by `: AnyObject`. ```swift public protocol WebSocketConnectionDelegate : AnyObject ``` -------------------------------- ### Configure Periodic Heartbeat with NWWebSocket (Swift) Source: https://context7.com/pusher/nwwebsocket/llms.txt This Swift code configures automatic periodic pings (heartbeats) to maintain WebSocket connection health using NWWebSocket. It requires the Network and NWWebSocket frameworks. The `ping(interval:)` method is used to set the ping frequency, and the `webSocketDidReceivePong` delegate method tracks received pongs. ```swift import Network import NWWebSocket class HeartbeatManager: WebSocketConnectionDelegate { var socket: NWWebSocket? var pongCount = 0 func setupHeartbeat() { let socketURL = URL(string: "wss://api.example.com/realtime")! socket = NWWebSocket(url: socketURL, connectAutomatically: true) socket?.delegate = self } func startHeartbeat() { // Ping every 30 seconds to keep connection alive socket?.ping(interval: 30.0) print("Started heartbeat: ping every 30 seconds") // For more aggressive keep-alive // socket?.ping(interval: 10.0) } func webSocketDidConnect(connection: WebSocketConnection) { print("Connected - starting heartbeat") startHeartbeat() } func webSocketDidReceivePong(connection: WebSocketConnection) { pongCount += 1 let timestamp = Date() print("[(timestamp)] Heartbeat pong #(pongCount) received - connection healthy") // Monitor connection health if pongCount % 10 == 0 { print("Connection has been stable for (pongCount * 30) seconds") } } func webSocketViabilityDidChange(connection: WebSocketConnection, isViable: Bool) { if !isViable { print("⚠️ Connection became unviable - heartbeat may fail") } else { print("✓ Connection viable again - heartbeat resumed") } } // Implement other required delegate methods... func webSocketDidDisconnect(connection: WebSocketConnection, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) { print("Disconnected - heartbeat stopped") pongCount = 0 } func webSocketDidAttemptBetterPathMigration(result: Result) {} func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {} func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {} } ``` -------------------------------- ### WebSocketConnectionDelegate Protocol Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Protocols.html The WebSocketConnectionDelegate protocol outlines the methods that a delegate object must implement to respond to events and manage the lifecycle of a WebSocket connection. ```APIDOC ## WebSocketConnectionDelegate Protocol ### Description Defines a delegate for a WebSocket connection. ### Method N/A (Protocol Definition) ### Endpoint N/A (Protocol Definition) ### Parameters N/A (Protocol Definition) ### Request Example N/A (Protocol Definition) ### Response #### Success Response (N/A) N/A (Protocol Definition) #### Response Example N/A (Protocol Definition) ``` -------------------------------- ### Connect to WebSocket - NWWebSocket Swift Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Protocols/WebSocketConnection.html Initiates a connection to the WebSocket endpoint. This function is part of the WebSocketConnection protocol. ```swift func connect() ``` -------------------------------- ### Send String Message over WebSocket Source: https://github.com/pusher/nwwebsocket/blob/main/docs/Classes/NWWebSocket.html Sends a UTF-8 formatted String over the WebSocket connection. Ensure the connection is established before sending. ```Swift open func send(string: String) ``` -------------------------------- ### Add NWWebSocket Dependency via Swift Package Manager (Package.swift) Source: https://github.com/pusher/nwwebsocket/blob/main/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/index.html Adds NWWebSocket as a dependency to a Swift Package Manager project. This can be done via Xcode's package dependency management or by editing the `Package.swift` file to include the NWWebSocket repository URL and version constraints. ```swift // swift-tools-version:5.1 import PackageDescription let package = Package( name: "YourPackage", products: [ .library( name: "YourPackage", targets: ["YourPackage"]), ], dependencies: [ .package(url: "https://github.com/pusher/NWWebSocket.git", .upToNextMajor(from: "0.5.2")), ], targets: [ .target( name: "YourPackage", dependencies: ["NWWebSocket"]) ] ) ```