ソースを参照

[PR #2060] Updated reachability to support [.connectionRequired, .isWWAN] combo.

These changes resolve issue #2052 where the reachability calcuation was incorrectly reporting the connection as reachable. When a user has install a simcard, but hasn’t yet selected a carrier, the connection is not reachable.
Marco Santarossa 8 年 前
コミット
68f4eb3f78

+ 13 - 10
Source/NetworkReachabilityManager.swift

@@ -182,21 +182,24 @@ public class NetworkReachabilityManager {
     // MARK: - Internal - Network Reachability Status
 
     func networkReachabilityStatusForFlags(_ flags: SCNetworkReachabilityFlags) -> NetworkReachabilityStatus {
-        guard flags.contains(.reachable) else { return .notReachable }
+        guard isNetworkReachable(with: flags) else { return .notReachable }
 
-        var networkStatus: NetworkReachabilityStatus = .notReachable
+        var networkStatus: NetworkReachabilityStatus = .reachable(.ethernetOrWiFi)
 
-        if !flags.contains(.connectionRequired) { networkStatus = .reachable(.ethernetOrWiFi) }
+    #if os(iOS)
+        if flags.contains(.isWWAN) { networkStatus = .reachable(.wwan) }
+    #endif
 
-        if flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic) {
-            if !flags.contains(.interventionRequired) { networkStatus = .reachable(.ethernetOrWiFi) }
-        }
+        return networkStatus
+    }
 
-        #if os(iOS)
-            if flags.contains(.isWWAN) { networkStatus = .reachable(.wwan) }
-        #endif
+    func isNetworkReachable(with flags: SCNetworkReachabilityFlags) -> Bool {
+        let isReachable = flags.contains(.reachable)
+        let needsConnection = flags.contains(.connectionRequired)
+        let canConnectAutomatically = flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic)
+        let canConnectWithoutUserInteraction = canConnectAutomatically && !flags.contains(.interventionRequired)
 
-        return networkStatus
+        return isReachable && (!needsConnection || canConnectWithoutUserInteraction)
     }
 }
 

+ 25 - 1
Tests/NetworkReachabilityManagerTests.swift

@@ -162,10 +162,22 @@ class NetworkReachabilityManagerTestCase: BaseTestCase {
         XCTAssertEqual(networkReachabilityStatus, .notReachable)
     }
 
+    func testThatManagerReturnsNotReachableStatusWhenConnectionIsRequired() {
+        // Given
+        let manager = NetworkReachabilityManager()
+        let flags: SCNetworkReachabilityFlags = [.reachable, .connectionRequired]
+
+        // When
+        let networkReachabilityStatus = manager?.networkReachabilityStatusForFlags(flags)
+
+        // Then
+        XCTAssertEqual(networkReachabilityStatus, .notReachable)
+    }
+    
     func testThatManagerReturnsNotReachableStatusWhenInterventionIsRequired() {
         // Given
         let manager = NetworkReachabilityManager()
-        let flags: SCNetworkReachabilityFlags = [.reachable, .connectionRequired, .connectionOnDemand, .interventionRequired]
+        let flags: SCNetworkReachabilityFlags = [.reachable, .connectionRequired, .interventionRequired]
 
         // When
         let networkReachabilityStatus = manager?.networkReachabilityStatusForFlags(flags)
@@ -222,5 +234,17 @@ class NetworkReachabilityManagerTestCase: BaseTestCase {
         // Then
         XCTAssertEqual(networkReachabilityStatus, .reachable(.wwan))
     }
+    
+    func testThatManagerReturnsNotReachableOnWWANStatusWhenIsWWANAndConnectionIsRequired() {
+        // Given
+        let manager = NetworkReachabilityManager()
+        let flags: SCNetworkReachabilityFlags = [.reachable, .isWWAN, .connectionRequired]
+
+        // When
+        let networkReachabilityStatus = manager?.networkReachabilityStatusForFlags(flags)
+
+        // Then
+        XCTAssertEqual(networkReachabilityStatus, .notReachable)
+    }
 #endif
 }