Swift – 获取设备的WIFI IP地址

我需要在Swift中获取iOS设备的IP地址。 这不是关于此的其他问题的重复! 我只需要获得WiFi IP地址,如果没有wifi地址 – 我需要处理它。 Stack Overflow上有一些关于它的问题,但是只有返回ip地址的函数。 例如(来自如何在swift中获取IP地址 ):

func getIFAddresses() -> [String] { var addresses = [String]() // Get list of all interfaces on the local machine: var ifaddr : UnsafeMutablePointer = nil if getifaddrs(&ifaddr) == 0 { // For each interface ... for (var ptr = ifaddr; ptr != nil; ptr = ptr.memory.ifa_next) { let flags = Int32(ptr.memory.ifa_flags) var addr = ptr.memory.ifa_addr.memory // Check for running IPv4, IPv6 interfaces. Skip the loopback interface. if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) { if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) { // Convert interface address to a human readable string: var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0) if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) == 0) { if let address = String.fromCString(hostname) { addresses.append(address) } } } } } freeifaddrs(ifaddr) } return addresses } 

在这里,我得到2个值 – 来自移动互联网(我认为)的地址和我需要的WiFi地址。 有没有其他方法来获得只有WiFi IP地址?

根据几个SO线程(例如, 什么是iOS网络接口名称?什么是pdp_ip?什么是ap? ),iOS设备上的WiFi接口始终具有名称“en0”。

您的代码(这似乎是我在如何获取swift中的IP地址时回答的:)检索所有正在运行的网络接口的IP地址列表。 它可以很容易地被修改为只返回“en0”接口的IP地址,实际上这就是我最初在该线程上回答的内容(这只是一个Swift翻译的答案, 如何以编程方式获取iphone的IP地址 ):

 // Return IP address of WiFi interface (en0) as a String, or `nil` func getWiFiAddress() -> String? { var address : String? // Get list of all interfaces on the local machine: var ifaddr : UnsafeMutablePointer = nil if getifaddrs(&ifaddr) == 0 { // For each interface ... var ptr = ifaddr while ptr != nil { defer { ptr = ptr.memory.ifa_next } let interface = ptr.memory // Check for IPv4 or IPv6 interface: let addrFamily = interface.ifa_addr.memory.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { // Check interface name: if let name = String.fromCString(interface.ifa_name) where name == "en0" { // Convert interface address to a human readable string: var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0) getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.memory.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) address = String.fromCString(hostname) } } } freeifaddrs(ifaddr) } return address } 

用法:

 if let addr = getWiFiAddress() { print(addr) } else { print("No WiFi address") } 

更新Swift 3:除了对Swift 3中的许多更改采用代码之外,迭代所有接口现在可以使用新的通用sequence()函数:

不要忘记在桥接头中添加#include

 // Return IP address of WiFi interface (en0) as a String, or `nil` func getWiFiAddress() -> String? { var address : String? // Get list of all interfaces on the local machine: var ifaddr : UnsafeMutablePointer? guard getifaddrs(&ifaddr) == 0 else { return nil } guard let firstAddr = ifaddr else { return nil } // For each interface ... for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { let interface = ifptr.pointee // Check for IPv4 or IPv6 interface: let addrFamily = interface.ifa_addr.pointee.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { // Check interface name: let name = String(cString: interface.ifa_name) if name == "en0" { // Convert interface address to a human readable string: var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) address = String(cString: hostname) } } } freeifaddrs(ifaddr) return address } 

创建桥接头并在其中包含#include

然后写这个方法

 func getIFAddresses() -> [String] { var addresses = [String]() // Get list of all interfaces on the local machine: var ifaddr : UnsafeMutablePointer = nil if getifaddrs(&ifaddr) == 0 { // For each interface ... for (var ptr = ifaddr; ptr != nil; ptr = ptr.memory.ifa_next) { let flags = Int32(ptr.memory.ifa_flags) var addr = ptr.memory.ifa_addr.memory // Check for running IPv4, IPv6 interfaces. Skip the loopback interface. if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) { if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) { // Convert interface address to a human readable string: var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0) if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) == 0) { if let address = String.fromCString(hostname) { addresses.append(address) } } } } } freeifaddrs(ifaddr) } return addresses } 

当我在我的viewController中调用此方法时,如var arr : NSArray = self.getIFAddresses()我在我的控制台中得到完美的响应

IP :(“10.0.0.94”)

从这个数组你可以随时访问它。 希望能帮助到你

Swift 4 – 获取设备的IP地址:

在桥接头中添加#include

这是获取IP地址所需的框架。

 class func getIPAddress() -> String? { var address: String? var ifaddr: UnsafeMutablePointer? = nil if getifaddrs(&ifaddr) == 0 { var ptr = ifaddr while ptr != nil { defer { ptr = ptr?.pointee.ifa_next } let interface = ptr?.pointee let addrFamily = interface?.ifa_addr.pointee.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { if let name: String = String(cString: (interface?.ifa_name)!), name == "en0" { var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) getnameinfo(interface?.ifa_addr, socklen_t((interface?.ifa_addr.pointee.sa_len)!), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) address = String(cString: hostname) } } } freeifaddrs(ifaddr) } return address } 

您可以使用以下代码获取IP地址:

注意:我已经使用了可访问性,以便在WiFi被更改为另一个时捕获新的IP地址。

  1. Podfile文件中

    pod 'ReachabilitySwift'然后install pod

  2. AppDelegate.swift文件中import ReachabilitySwift

    注意:如果它提示无法找到ReachabilitySwift模块的错误,则只需复制并粘贴它。 有用!

  3. didFinishLaunchingOptions函数

     NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged), name: ReachabilityChangedNotification, object: reachability) do{ try reachability.startNotifier() } catch { print("could not start reachability notifier") } 
  4. 然后在AppDelegate文件中的代码下面复制粘贴

     func reachabilityChanged(note: NSNotification) { let reachability = note.object as! Reachability if reachability.isReachable { if reachability.isReachableViaWiFi { print("Reachable via WiFi") } else { print("Reachable via Cellular") } setIPAddress() } else { ipAddress = "" // No IP captures print("Network not reachable") } } func setIPAddress() { if let addr = self.getWiFiAddress() { print("ipAddress : \(addr)") ipAddress = addr } else { ipAddress = "" // No IP captures print("No WiFi address") } } // Return IP address of WiFi interface (en0) as a String, or `nil` func getWiFiAddress() -> String? { var address : String? // Get list of all interfaces on the local machine: var ifaddr : UnsafeMutablePointer? guard getifaddrs(&ifaddr) == 0 else { return nil } guard let firstAddr = ifaddr else { return nil } // For each interface ... for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { let interface = ifptr.pointee // Check for IPv4 or IPv6 interface: let addrFamily = interface.ifa_addr.pointee.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { // Check interface name: let name = String(cString: interface.ifa_name) if name == "en0" { // Convert interface address to a human readable string: var addr = interface.ifa_addr.pointee var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) getnameinfo(&addr, socklen_t(interface.ifa_addr.pointee.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) address = String(cString: hostname) } } } freeifaddrs(ifaddr) return address } 
  5. 在Bridging-Header文件#include添加它

    如果您没有此文件,则可以创建它检查此链接

6。

 func applicationWillEnterForeground(_ application: UIApplication) { // Post notification NotificationCenter.default.post(name: ReachabilityChangedNotification, object: reachability) // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } 
  1. 如果要删除观察者,则:

     reachability.stopNotifier() NSNotificationCenter.defaultCenter().removeObserver(self,name: ReachabilityChangedNotification,object: reachability) 
 func getIPAddress() -> String { var address: String = "error" var interfaces: ifaddrs? = nil var temp_addr: ifaddrs? = nil var success: Int = 0 // retrieve the current interfaces - returns 0 on success success = getifaddrs(interfaces) if success == 0 { // Loop through linked list of interfaces temp_addr = interfaces while temp_addr != nil { if temp_addr?.ifa_addr?.sa_family == AF_INET { // Check if interface is en0 which is the wifi connection on the iPhone if (String(utf8String: temp_addr?.ifa_name) == "en0") { // Get NSString from C String address = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr)) } } temp_addr = temp_addr?.ifa_next } } // Free memory freeifaddrs(interfaces) return address } 
Interesting Posts