当前位置: 首页 > 面试题库 >

Swift-获取设备的WIFI IP地址

孔宇
2023-03-14
问题内容

我需要在Swift中获取iOS设备的IP地址。这不是其他有关此问题的重复!如果没有wifi IP地址,我只需要获取WiFiIP地址-我需要处理它。关于堆栈溢出有一些问题,但是只有返回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线程(例如,iOS网络接口名称的确切含义是什么?pdp_ip是什么?ap是什么?),iOS设备上的WiFi接口始终具有名称“ en0”。

您的代码(这似乎是我在“ 如何迅速获取IP地址”中回答的内容)检索 所有 正在运行的网络接口的IP地址的列表。可以轻松地修改它,使其仅返回“en0”接口的IP地址,而实际上这正是我 最初 在该线程处回答的(这只是对[如何以编程方式获取iphoneip地址的回答的快速翻译。):

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

对于那些想要寻找比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。

guard let wifiIp = getAddress(for: .wifi) else { return }

guard let cellularIp = getAddress(for: .cellular) else { return }



 类似资料:
  • 问题内容: 我正在寻找一种方法(使用python)从本地网络上的设备获取地址。 地址是已知的。 目标是建立一个脚本,该脚本将定期轮询IP地址数据库,以确保mac地址没有更改,如果有更改,则将电子邮件警报发送给我自己。 问题答案: 用Python回答问题取决于您的平台。我没有Windows,因此以下解决方案可在我写过的Linux机器上使用。对正则表达式进行小的更改将使其在OS X中运行。 首先,您必

  • 我目前正在使用 获取执行设备的IP地址。如果该设备连接到一个“公共”wlan网络,并且该设备连接到一个wifi网络,该网络由另一个Android设备通过hotspot托管,则该功能正常。如果设备未连接到任何wifi网络,则返回“0.0.0.0”(正确)。但如果设备通过提供热点来承载wifi网络,methode仍然返回“0.0.0.0”。我如何在“自己的wifi网络”中获取热点提供设备的真实IP地址

  • 我检查了下面的代码以获取ipv6地址,这段代码返回了全局单播地址,比如“2001:x:x…”。但我想获得链接本地地址,比如“fe80:…”。如何使用以下代码获取链接本地地址?

  • 通过 id 获取 device 信息 参数说明 字段 类型 必须? 说明 deviceId String 是 设备Id 接口定义 Swift: let device = RokidMobileSDK.device.getDevice(deviceId: String) -> RKDevice? Objc: RKDevice * device = [RokidMobileSDK.device ge

  • 问题内容: 我正在我的android设备上测试adMob,并在获取说明文件之后,尝试获取执行adRequest的设备ID。但是,我无法在logCat中找到设备ID!我做错了什么? 编辑:这不是重复的,其他帖子中的那些方法对我不起作用。 问题答案: final TelephonyManager tm =(TelephonyManager)getBaseContext().getSystemServi

  • 问题内容: 如何获取Android设备名称?我正在使用HTC的愿望。当我通过HTC Sync将其连接时,软件将显示名称 “ HTC Smith” 。我想通过代码获取此名称。 在Android中怎么可能? 问题答案: 为了获得Android设备名称,您只需要添加一行代码即可: 在这里找到:getting-android-device- name