1 import ExpoModulesCore 2 import SystemConfiguration 3 import Network 4 5 public final class NetworkModule: Module { 6 private let monitor = NWPathMonitor() 7 private let monitorQueue = DispatchQueue.global(qos: .default) 8 definitionnull9 public func definition() -> ModuleDefinition { 10 Name("ExpoNetwork") 11 12 OnCreate { 13 monitor.start(queue: monitorQueue) 14 } 15 16 AsyncFunction("getIpAddressAsync") { () -> String? in 17 return try getIPAddress() 18 } 19 20 AsyncFunction("getNetworkStateAsync") { 21 return getNetworkStateAsync() 22 } 23 24 OnDestroy { 25 monitor.cancel() 26 } 27 } 28 getIPAddressnull29 private func getIPAddress() throws -> String { 30 var address = "0.0.0.0" 31 var ifaddr: UnsafeMutablePointer<ifaddrs>? 32 33 let error = getifaddrs(&ifaddr) 34 35 guard error == 0 else { 36 throw IpAddressException(error) 37 } 38 39 guard let firstAddr = ifaddr else { 40 return address 41 } 42 43 for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { 44 let temp = ifptr.pointee 45 let family = temp.ifa_addr.pointee.sa_family 46 47 if family == UInt8(AF_INET) { 48 let name = String(cString: temp.ifa_name) 49 if name == "en0" || name == "en1" { 50 var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) 51 getnameinfo( 52 temp.ifa_addr, 53 socklen_t(temp.ifa_addr.pointee.sa_len), 54 &hostname, 55 socklen_t(hostname.count), 56 nil, 57 socklen_t(0), 58 NI_NUMERICHOST) 59 address = String(cString: hostname) 60 } 61 } 62 } 63 64 freeifaddrs(ifaddr) 65 return address 66 } 67 getNetworkStateAsyncnull68 private func getNetworkStateAsync() -> [String: Any] { 69 let path = monitor.currentPath 70 let isConnected = path.status == .satisfied 71 var currentNetworkType = NetworkType.unknown 72 73 if !isConnected { 74 return [ 75 "type": NetworkType.none.description, 76 "isConnected": isConnected, 77 "isInternetReachable": isConnected 78 ] 79 } 80 81 let connectionType = NWInterface 82 .InterfaceType 83 .allCases 84 .filter { path.usesInterfaceType($0) } 85 .first 86 87 switch connectionType { 88 case .wifi: 89 currentNetworkType = .wifi 90 case .cellular: 91 currentNetworkType = .cellular 92 default: 93 currentNetworkType = .unknown 94 } 95 96 return [ 97 "type": currentNetworkType.description, 98 "isConnected": isConnected, 99 "isInternetReachable": isConnected 100 ] 101 } 102 } 103