根据一些SO线程(例如,
What exactly means iOS networking interface name? what's pdp_ip ? what's ap?),iOS设备上的WiFi接口始终具有名称"en0"。
您的代码(似乎是我在
How to get Ip address in swift中所回答的 :) )检索所有运行中网络接口的IP地址列表。它可以轻松地修改为仅返回“en0”接口的IP地址,并且实际上这就是我最初在该线程中回答的内容(这只是
how to get ip address of iphone programmatically答案的Swift翻译)。
func getWiFiAddress() -> String? {
var address : String?
var ifaddr : UnsafeMutablePointer<ifaddrs> = nil
if getifaddrs(&ifaddr) == 0 {
var ptr = ifaddr
while ptr != nil {
defer { ptr = ptr.memory.ifa_next }
let interface = ptr.memory
let addrFamily = interface.ifa_addr.memory.sa_family
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
if let name = String.fromCString(interface.ifa_name) where name == "en0" {
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>
func getWiFiAddress() -> String? {
var address : String?
var ifaddr : UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return nil }
guard let firstAddr = ifaddr else { return nil }
for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
let interface = ifptr.pointee
let addrFamily = interface.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
let name = String(cString: interface.ifa_name)
if 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
}
对于那些不仅仅想要WIFI IP的人,你可以稍微修改一下这段代码
func getAddress(for network: Network) -> String? {
var address: String?
var ifaddr: UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return nil }
guard let firstAddr = ifaddr else { return nil }
for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
let interface = ifptr.pointee
let addrFamily = interface.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
let name = String(cString: interface.ifa_name)
if name == network.rawValue {
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
}
enum Network: String {
case wifi = "en0"
case cellular = "pdp_ip0"
//... case ipv4 = "ipv4"
//... case ipv6 = "ipv6"
}
那么我们也可以访问移动设备的IP地址。
如果无法获取WiFi IP地址,则保护该代码:guard let wifiIp = getAddress(for: .wifi) else { return }
&
如果无法获取蜂窝网络IP地址,则保护该代码:guard let cellularIp = getAddress(for: .cellular) else { return }