1. ホーム
  2. ios

Swift - デバイスのWIFI IPアドレスの取得

2023-07-09 01:35:28

質問

私はSwiftでiOSデバイスのIPアドレスを取得する必要があります。これはこれについての他の質問の重複ではありません!私はWiFi IPアドレスのみを取得する必要があります。私はWiFi IPアドレスのみを取得する必要があり、Wifi IPアドレスがない場合、私はそれを処理する必要があります。Stack Overflowでそれに関するいくつかの質問がありますが、ipアドレスを返す関数しかありません。例えば(以下 swiftで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" という名前を持っています。

あなたのコード (これは、私が次の場所で回答したものと思われます。 swiftでIpアドレスを取得する方法 :) のIPアドレスのリストを取得します。 全て のIPアドレスのリストを取得します。のIPアドレスだけを返すように簡単に変更できます。 を返すように修正することができます。 はもともと で答えていたことです。 そのスレッドで答えたことです (そして、これはちょうど Swift 翻訳の への回答です。 プログラム的にiPhoneのIPアドレスを取得する方法 ):

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