1diff --git a/android/src/main/java/expo/modules/network/NetworkModule.kt b/android/src/main/java/expo/modules/network/NetworkModule.kt
2index 5e513271533a6c99bcfe8fff245e84c80ac55621..f7353c3d2eb01798b083359e1554556303bf0f0e 100644
3--- a/android/src/main/java/expo/modules/network/NetworkModule.kt
4+++ b/android/src/main/java/expo/modules/network/NetworkModule.kt
5@@ -89,6 +89,11 @@ class NetworkModule : Module() {
6 }
7 }
9+ // Android reports a lifted network block only through this callback.
10+ override fun onBlockedStatusChanged(network: android.net.Network, blocked: Boolean) {
11+ asyncEmitNetworkState(DELAY_MS)
12+ }
13+
14 override fun onCapabilitiesChanged(network: android.net.Network, networkCapabilities: NetworkCapabilities) {
15 asyncEmitNetworkState(DELAY_MS)
16 }
17diff --git a/ios/NetworkModule.swift b/ios/NetworkModule.swift
18index ce150f792f0a717696b24d3930d8ea55b1dc12a6..ec1d2cdd11861f8862ba58c20fd7f1c75845efdb 100644
19--- a/ios/NetworkModule.swift
20+++ b/ios/NetworkModule.swift
21@@ -101,10 +101,18 @@ public final class NetworkModule: Module {
22 // since we want to wait for the result to be updated once:
23 let tempMonitor = NWPathMonitor()
24 var tempPath: NWPath?
25+ let pathLock = NSLock()
27 let semaphore = DispatchSemaphore(value: 0)
29 tempMonitor.pathUpdateHandler = { updatedPath in
30+ // Cancellation does not drain queued updates. Publish only the first path
31+ // and synchronize its retain with the caller reading it on another queue.
32+ pathLock.lock()
33+ defer { pathLock.unlock() }
34+ guard tempPath == nil else {
35+ return
36+ }
37 tempPath = updatedPath
38 semaphore.signal() // Notify that we got the path
39 }
40@@ -122,6 +130,8 @@ public final class NetworkModule: Module {
41 return nil
42 }
44+ pathLock.lock()
45+ defer { pathLock.unlock() }
46 return tempPath
47 }