Ping DNS to check internet connection

I want to check if the device has a internet connection or not by pinging DNS "8.8.8.8".

connection.send(content: content, completion: .contentProcessed {[weak self] error in 

send function is not returning any error even if the host is unreachable.

I am checking if I can receive the data or not but connection.receiveMessage function never returns.

This is the complete code which I am following:

    private let networkMonitor = NWPathMonitor()
    private var connection: NWConnection
    @MainActor var isConnectedToInternet = false

    init(host: NWEndpoint.Host = "8.8.8.8",
         port: NWEndpoint.Port = 53) {
        let endpoint = NWEndpoint.hostPort(host: host, port: port)
        connection = NWConnection(to: endpoint, using: .udp)

        startMonitoring()
    }

    private func startMonitoring() {
        networkMonitor.pathUpdateHandler = { [weak self] path in
            guard let self else { return }

            ping(callback: { isSuccess in
                print("***** ping status:", isSuccess)
                Task { @MainActor in
                    self.isConnectedToInternet = isSuccess
                }
            })
        }

        let queue = DispatchQueue(label: QueueLabel.networkMonitor)
        networkMonitor.start(queue: queue)
    }

    func ping(
        host: NWEndpoint.Host = "8.8.8.8",
        port: NWEndpoint.Port = 53,
        callback: @escaping ((Bool) -> Void)
    ) {

        var didSendState = false

        connection.stateUpdateHandler = {[weak self] state in
            guard let self = self else { return }
            guard !didSendState else {
                if state != .cancelled {
                    cancel(connection)
                }
                return
            }

            switch state {
            case .ready:

                // State is ready now send data
                let content = "Ping".data(using: .utf8)
                let startTime = Date()

                connection.send(content: content, completion: .contentProcessed {[weak self] error in
                    guard let self = self else { return }
                    if error != nil {
                        callback(false)
                        didSendState = true
                        cancel(connection)
                    } else {
                        print("Ping sent, waiting for response...")

                        connection.receiveMessage { [weak self] content, _, _, receiveError in
                            guard let self = self else { return }
                            if let receiveError {
                                print("Error receiving ping: \(receiveError.localizedDescription)")
                                callback(false)
                            } else if let content = content, String(data: content, encoding: .utf8) == "Ping" {
                                let roundTripTime = Date().timeIntervalSince(startTime)
                                print("Ping received! Round-trip time: \(roundTripTime) seconds")
                                callback(true)
                            } else {
                                print("Invalid response received")
                                callback(true)
                            }
                            didSendState = true
                            cancel(connection)
                        }
                    }
                })
            case .failed( _), .waiting( _), .cancelled:
                didSendState = true
                callback(false)
            case .setup, .preparing:
                // No callback because the ping has not yet succeeded or failed
                break
            @unknown default:
                didSendState = true
                callback(false)
                // We don't know what this unknown default means, so cancel pings to be safe
                cancel(connection)
            }
        }

        connection.start(queue: .main)
    }

    func cancel(_ connection: NWConnection) {
        connection.cancel()
    }
}

Can anyone please help what I am doing wrong.

Can anyone please help what I am doing wrong.

Many many things )-:

Let’s start with the fundamentals. What’s your high-level goal here?

You wrote:

I want to check if the device has a internet connection or not

which is problematic because the Internet isn’t a single thing. Let’s say there’s some sort of outage at Google and 8.8.8.8 falls over. That doesn’t take down the Internet as a whole [1]. If your app prevents the user from getting work done because this service has fallen over, that’s not a great result.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] It’d probably take down a lot of things, but hopefully not everything (-:

Ping DNS to check internet connection
 
 
Q