我需要在SWIFT中获取iOS设备的IP地址.这不是关于这个的其他问题的重复!我只需要获得WiFi IP地址,如果没有WiFi IP地址-我需要处理它.关于堆栈溢出有几个问题,但只有返回IP地址的函数.例如(从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
}

这里我有两个值-来自移动互联网的地址(我想)和我需要的WiFi地址.有没有其他方法可以只获取WiFi IP地址?

推荐答案

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 Ip address in swift:回答的代码)检索正在运行的all个网络接口的IP地址列表.可以很容易地将其修改为仅返回IP地址 "en0"接口,实际上这就是I originally拥有的 在那个帖子上回答(这只是快速翻译的 回答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")
}

Update for Swift 3:除了将代码应用于 many changes in Swift 3, 在所有接口上迭代现在可以使用新的泛化 sequence()功能:

NOT是否忘记在桥接标头中添加#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
}

For those of you who came looking for more than the WIFI IP you could modify this code a little

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 }

Ios相关问答推荐

如何使用UICollectionView Compositionallayout在UIKit中正确渲染远程图像

如何修复使用EFCore和SQLite的.Net MAUI iOS应用程序上的当前应用程序不支持NullabilityInfoContext?

当文本为空时,具有垂直轴的SwiftUI文本字段不会与FirstTextBaseline对齐

NSHashTable要求任何MyCustomProtocolAnyObject都是类类型

SwiftUI:.toolbar 不适用于 UITextView

Flutter iOS 键盘问题:. TextInputType.number 中缺少字符

NavigationLink 只能在文本部分点击

如何更改 SwiftUI 弹出视图的大小?

包装在 AnyView 中时 UIViewControllerRepresentable 无法正常工作

通过函数使用 Gesture 时,键入任何视图不能符合视图

一个 SwiftUI 视图中的多个垂直滚动视图

Xcode 14 弃用了位码 - 但为什么呢?

Swift枚举继承

从 NSData 或 UIImage 中查找图像类型

将 iPhone xib 转换为 iPad xib?

try 在 iOS 中处理后退导航按钮操作

如何像在 Facebook 应用程序中一样以编程方式打开设置?

UICollectionView flowLayout 没有正确包装单元格

如何使用 presentModalViewController 创建透明视图

未找到符号:kUTTypeImage