1 Reply
      Latest reply on Feb 12, 2020 9:25 PM by meaton
      dingfromchiyoda-ku Level 1 Level 1 (0 points)

        I have a problem with the different behavior when using SCNetworkReachability if the iPhone is running a packet tunnel based on NEPacketTunnelNetwork

                var flags: SCNetworkReachabilityFlags =
        SCNetworkReachabilityFlags(rawValue: 0)
                let isReachable = flags == .reachable
                let needsConnection = flags == .connectionRequired
                return isReachable && !needsConnection
        

        if I use the [let isReachable = flags == .reachable],

        The resulte of isReachable will be False

         

        However,if I use the code of [let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0] like below.

        The result will be True

                var flags: SCNetworkReachabilityFlags =SCNetworkReachabilityFlags(rawValue: 0)
                let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
                let needsConnection = flags == .connectionRequired
                return isReachable && !needsConnection
        

         

        The API reference the [reachable] and [kSCNetworkFlagsReachable] has the same describe :

        "The specified node name or address can be reached using the current network configuration"

         

        Can anybady tell me which one is the correct behavior that should be used?

        • Re: The incorrect behavior of SCNetworkReachability
          meaton Apple Staff Apple Staff (80 points)

          Try using the contains() to check for the existence of a set flag in SCNetworkReachabilityFlags.  For example:

           

          let isReachable = flags.contains(.reachable)
          let needsConnection = flags.contains(.connectionRequired)
          let isReachableOnWWAN = flags.contains(.isWWAN)

           

          Another API you could also evaluate as an alternative to SCNetworkReachability would be NWPathMonitor.  NWPathMonitor provides an API to fetch the current network path and receive updates when the network path changes.

           

          let nwPathMonitor = NWPathMonitor() 
          nwPathMonitor.pathUpdateHandler = { path in 
              
              if path.usesInterfaceType(.wifi) {  
                  os_log("Path is Wi-Fi") 
              } else if path.usesInterfaceType(.cellular) { 
                  os_log("Path is Cellular") 
              } else if path.usesInterfaceType(.wiredEthernet) { 
                  os_log("Path is Wired Ethernet") 
              } else if path.usesInterfaceType(.loopback) { 
                  os_log("Path is Loopback") 
              } else if path.usesInterfaceType(.other) { 
                  os_log("Path is other") 
              } 
          } 
          nwPathMonitor.start(queue: .main) 

           

          Matt Eaton

          DTS Engineering, CoreOS

          meaton3 at apple.com