Swift - 获取设备的 WIFI IP 地址 [英] Swift - Get device's WIFI IP Address
问题描述
我需要在 Swift 中获取 iOS 设备的 IP 地址.这不是与此相关的其他问题的重复!我只需要获取 WiFi IP 地址,如果没有 WiFi IP 地址 - 我需要处理它.Stack Overflow 上有一些关于它的问题,但只有返回 ip 地址的函数.例如(来自如何快速获取IP地址):
I need to get IP Address of iOS device in Swift. This is not a duplicate of other questions about this! I need to get only WiFi IP address, if there is no wifi ip address - I need to handle it. There are a few questions about it on Stack Overflow, but there are only functions that return ip addresses. For example (from How to get Ip address in swift):
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 地址?
Here I get 2 values - address from mobile internet(I think) and WiFi address I need. Is there any other way to get ONLY WiFi IP Address?
推荐答案
根据几个 SO 线程(例如 iOS 网络接口名称究竟是什么意思?pdp_ip 是什么?ap 是什么?),iOS 设备上的 WiFi 接口总是名为en0".
According to several SO threads (e.g. What exactly means iOS networking interface name? what's pdp_ip ? what's ap?), the WiFi interface on an iOS device always has then name "en0".
你的代码(这似乎是我在 How to get Ipswift 中的地址 :) 检索所有 正在运行的网络接口的 IP 地址列表.可以很容易地修改为仅返回 IP 地址en0"界面,实际上这就是我最初所拥有的在那个线程上回答(这只是 Swift 翻译如何以编程方式获取 iphone 的 ip 地址的答案):
Your code (which seems to be what I answered at How to get Ip address in swift :) retrieves a list of the IP addresses of all running network interfaces. It can easily be modified to return only the IP address of the "en0" interface, and actually that is what I originally had answered at that thread (and this is just a Swift translation of the answer to how to get ip address of iphone programmatically):
// 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()
函数:
Update for Swift 3: In addition to adopting the code to the
many changes in Swift 3,
iterating over all interfaces can now use the new generalized
sequence()
function:
不要不要忘记在桥接头中添加#include
Do NOT forget to add #include <ifaddrs.h>
in your bridging header
// 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
}
<小时>
对于那些来寻找不仅仅是WIFI IP的人,你可以稍微修改一下这个代码
func getAddress(for network: Network) -> 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 == network.rawValue {
// 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
}
enum Network: String {
case wifi = "en0"
case cellular = "pdp_ip0"
//... case ipv4 = "ipv4"
//... case ipv6 = "ipv6"
}
然后我们也可以访问蜂窝 IP.
Then we have access to the cellular IP as well.
guard let wifiIp = getAddress(for: .wifi) else { return }
&
guard letcellularIp = getAddress(for: .cellular) else { return }
这篇关于Swift - 获取设备的 WIFI IP 地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!