Swift – 获取设备的IP地址

我需要在Swift中获取iOS设备的IP地址。 这不是关于这个问题的其他问题的重复! 我只需要获得WiFi的IP地址,如果没有wifi的IP地址 – 我需要处理它。 关于堆栈溢出有几个问题,但只有返回IP地址的函数。 例如(从如何获得IP地址在迅速 ):

func getIFAddresses() -> [String] { var addresses = [String]() // Get list of all interfaces on the local machine: var ifaddr : UnsafeMutablePointer<ifaddrs> = 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线程(例如, 什么意思是iOSnetworking接口名称?什么是pdp_ip?什么是ap? ),iOS设备上的WiFi接口总是命名为“en0”。

你的代码(这似乎是我在回答如何得到IP地址在迅速 :)回答所有正在运行的networking接口的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<ifaddrs> = 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 <ifaddrs.h>

 // 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<ifaddrs>? 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 } 

创build桥接头并在其中包含#include <ifaddrs.h>

然后写这个方法

 func getIFAddresses() -> [String] { var addresses = [String]() // Get list of all interfaces on the local machine: var ifaddr : UnsafeMutablePointer<ifaddrs> = 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”)

从这个数组中,你可以访问任何地方你想要的。 希望能帮助到你

您可以使用下面的代码获取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<ifaddrs>? 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 OpeningAngleBracket ifaddrs.h ClosingAngleBracket

    如果你没有这个文件,那么你可以创build它检查这个链接

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 } 

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

在桥接头中添加#include<ifaddrs.h>

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

 class func getIPAddress() -> String? { var address: String? var ifaddr: UnsafeMutablePointer<ifaddrs>? = 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 }