📜  获取 wifi、有线和蜂窝的 IPAddress - Swift (1)

📅  最后修改于: 2023-12-03 15:27:48.482000             🧑  作者: Mango

获取wifi、有线和蜂窝的IPAddress - Swift

在iOS开发中,获取设备的IPAddress是一个常见的需求,因为它可以帮助我们识别用户所在的网络环境,从而提供更好的用户体验。本文将介绍如何使用Swift来获取设备的IPAddress,并分别展示获取wifi、有线和蜂窝网络的IPAddress的方法。

获取wifi网络的IPAddress
func getIPAddress() -> String? {
    var address: String?
    var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
    guard getifaddrs(&ifaddr) == 0 else { return nil }
    guard let firstAddr = ifaddr else { return nil }
    defer { freeifaddrs(ifaddr) }
    for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
        let flags = Int32(ptr.pointee.ifa_flags)
        var addr = ptr.pointee.ifa_addr.pointee
        guard (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) else { continue }
        if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
            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) {
                guard let addr = String(cString: hostname, encoding: .ascii) else { continue }
                if addr.hasPrefix("192.168") || addr.hasPrefix("10.") {
                    address = addr
                    break
                }
            }
        }
    }
    return address
}

解释:

  • 首先通过getifaddrs函数获得本机的网络接口列表。
  • 遍历所有的网络接口,判断该接口是否为wifi网络。
  • 如果是,则通过getnameinfo函数获取IPAddress,并判断是否为合法的ipv4地址。

返回的IPAddress是一个字符串,例如:"192.168.1.100"。如果获取失败,则返回nil。

获取有线网络的IPAddress
func getEthernetAddress() -> String? {
    var address: String?
    var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
    guard getifaddrs(&ifaddr) == 0 else { return nil }
    guard let firstAddr = ifaddr else { return nil }
    defer { freeifaddrs(ifaddr) }
    for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
        let flags = Int32(ptr.pointee.ifa_flags)
        var addr = ptr.pointee.ifa_addr.pointee
        guard (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) else { continue }
        if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
            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) {
                guard let addr = String(cString: hostname, encoding: .ascii) else { continue }
                if addr.hasPrefix("169.254") {
                    address = addr
                    break
                }
            }
        }
    }
    return address
}

解释:

  • 和获取wifi网络的IPAddress类似,遍历所有的网络接口,判断该接口是否为有线网络。
  • 如果是,则通过getnameinfo函数获取IPAddress,并判断是否为合法的ipv4地址。

返回的IPAddress是一个字符串,例如:"169.254.1.2"。如果获取失败,则返回nil。

获取蜂窝网络的IPAddress
import CoreTelephony

func getCellularAddress() -> String? {
    let networkInfo = CTTelephonyNetworkInfo()
    guard let carrier = networkInfo.subscriberCellularProvider else { return nil }
    if carrier.isoCountryCode == "cn" || carrier.mobileNetworkCode == "460" {
        guard let address = getIPAddress() else { return nil }
        return address
    }
    return nil
}

解释:

  • 获取CTTelephonyNetworkInfo对象。
  • 使用CTTelephonyNetworkInfo对象获取当前设备所使用的运营商。
  • 判断是否为中国移动网络(中国移动的二进制编码为"460"),如果是,则调用获取wifi网络的IPAddress的函数获取IPAddress。
  • 如果不是,则返回nil。

返回的IPAddress是一个字符串,例如:"192.168.1.100"。如果获取失败,则返回nil。

总结:

本文介绍了Swift在iOS开发中获取设备的IPAddress的方法,并提供了获取wifi、有线和蜂窝网络IPAddress的代码片段。无论您是开发网络应用、测试网络环境,还是需要读取本机IPAddress的需求,都可以通过本文获得相关的帮助。