我如何获得本地IpAddress?
当我使用该功能时,getifaddrs()我将无法再继续使用。我不能使用该功能。
getifaddrs()
是否有其他方法可以执行此操作,或者我是否以错误的方式进行操作?
在讨论中发现,OP需要Mac上的接口地址,而不是我最初想的那样在iOS设备上。问题中引用的代码将检查接口名称“en0”,它是iPhone上的WiFi接口。在Mac上,改为检查任何“正在运行”的界面更有意义。因此,我重写了答案。现在,它是“检测任何连接的网络”中代码的快速翻译 。
getifaddrs()在中定义<ifaddrs.h>,默认情况下不包含。因此,您必须创建一个桥接头并添加
<ifaddrs.h>
#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 ... var ptr = ifaddr while ptr != nil { defer { ptr = ptr.memory.ifa_next } let flags = Int32(ptr.memory.ifa_flags) let 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(ptr.memory.ifa_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 }
Swift 3的更新: 除了 对Swift 3 的许多更改采用代码之外 ,对所有接口进行迭代现在还可以使用新的通用 sequence()函数:
sequence()
func getIFAddresses() -> [String] { var addresses = [String]() // Get list of all interfaces on the local machine: var ifaddr : UnsafeMutablePointer<ifaddrs>? guard getifaddrs(&ifaddr) == 0 else { return [] } guard let firstAddr = ifaddr else { return [] } // For each interface ... for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { let flags = Int32(ptr.pointee.ifa_flags) let addr = ptr.pointee.ifa_addr.pointee // 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](repeating: 0, count: Int(NI_MAXHOST)) if (getnameinfo(ptr.pointee.ifa_addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) == 0) { let address = String(cString: hostname) addresses.append(address) } } } } freeifaddrs(ifaddr) return addresses }