You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 如何实现单次用户互联网连接状态检测

单次网络连接状态检测实现方案

所有单次检测的本质都是主动触发一次连通性校验,不需要维持长时监听,避免不必要的性能开销,不同场景的实现方案如下:

前端(浏览器/跨端Web方案)

  • 核心逻辑:主动发起一次低开销的HEAD请求到高可用的公共静态资源,不需要拉取完整内容,只校验响应状态即可判断公网连通性
  • 注意:不要用navigator.onLine,该API只能判断设备是否连接到局域网,无法判断是否能访问公网
  • 示例代码:
async function checkInternetConnectivity() {
  try {
    // 超时时间控制在3s内,避免长时间等待
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 3000);
    const response = await fetch('https://www.gstatic.com/generate_204', {
      method: 'HEAD',
      signal: controller.signal
    });
    clearTimeout(timeoutId);
    return response.ok;
  } catch (err) {
    return false;
  }
}
// 调用方式
const isConnected = await checkInternetConnectivity();

Android 原生实现

  • 核心逻辑:用ConnectivityManager单次获取当前网络状态,配合一次短连接校验公网连通性,不需要注册持续性监听回调
  • 所需权限:ACCESS_NETWORK_STATE、INTERNET
  • 示例代码:
suspend fun isInternetAvailable(): Boolean {
    val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetwork = connectivityManager.activeNetwork ?: return false
    val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
    // 先判断是否已连接到网络
    if (!capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) return false
    // 再校验公网连通性
    return runCatching {
        val socket = Socket()
        socket.connect(InetSocketAddress("8.8.8.8", 53), 3000)
        socket.close()
        true
    }.getOrDefault(false)
}

iOS 原生实现

  • 核心逻辑:用NWPathMonitor单次触发状态获取,拿到结果后立即停止监听,配合公网连通性校验,不会产生持续运行的开销
  • 示例代码:
func checkInternetConnectivity(completion: @escaping (Bool) -> Void) {
    let monitor = NWPathMonitor()
    monitor.pathUpdateHandler = { path in
        monitor.cancel() // 拿到一次状态后直接停止监听
        guard path.status == .satisfied else {
            completion(false)
            return
        }
        // 校验公网连通性
        let url = URL(string: "https://captive.apple.com/hotspot-detect.html")!
        let task = URLSession.shared.dataTask(with: url) { _, response, error in
            DispatchQueue.main.async {
                completion(error == nil && (response as? HTTPURLResponse)?.statusCode == 200)
            }
        }
        task.resume()
    }
    monitor.start(queue: DispatchQueue.global())
}

内容的提问来源于stack exchange,提问作者Boothosh81

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 13:54:01