objective macintosh framework developer apple ios swift network-programming

macintosh - swift ios documentation



Swift: obtenga la dirección IP WIFI del dispositivo (10)

Necesito obtener la dirección IP del dispositivo iOS en Swift. ¡Esto no es un duplicado de otras preguntas sobre esto! Necesito obtener solo la dirección IP WiFi, si no hay una dirección IP wifi, necesito manejarla. Hay algunas preguntas al respecto en Stack Overflow, pero solo hay funciones que devuelven direcciones IP. Por ejemplo (de Cómo obtener la dirección IP en 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 }

Aquí obtengo 2 valores: dirección de Internet móvil (creo) y dirección WiFi que necesito. ¿Hay alguna otra forma de obtener SOLO la dirección IP de WiFi?


Cree un encabezado de puente e incluya #include <ifaddrs.h> en él.

luego escribe este método

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 }

cuando llamo a este método en mi viewController como var arr : NSArray = self.getIFAddresses() obtengo una respuesta perfecta en mi consola como

IP :( "10.0.0.94")

desde esta matriz puedes acceder a donde quieras. Espero eso ayude


Extensión de servicio UIDevice Swift 4.2 que evita UIDevice y admite direcciones IP celulares y cableadas:

import UIKit extension UIDevice { private struct InterfaceNames { static let wifi = ["en0"] static let wired = ["en2", "en3", "en4"] static let cellular = ["pdp_ip0","pdp_ip1","pdp_ip2","pdp_ip3"] static let supported = wifi + wired + cellular } func ipAddress() -> String? { var ipAddress: String? var ifaddr: UnsafeMutablePointer<ifaddrs>? if getifaddrs(&ifaddr) == 0 { var pointer = ifaddr while pointer != nil { defer { pointer = pointer?.pointee.ifa_next } guard let interface = pointer?.pointee, interface.ifa_addr.pointee.sa_family == UInt8(AF_INET) || interface.ifa_addr.pointee.sa_family == UInt8(AF_INET6), let interfaceName = interface.ifa_name, let interfaceNameFormatted = String(cString: interfaceName, encoding: .utf8), InterfaceNames.supported.contains(interfaceNameFormatted) else { continue } 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) guard let formattedIpAddress = String(cString: hostname, encoding: .utf8), !formattedIpAddress.isEmpty else { continue } ipAddress = formattedIpAddress break } freeifaddrs(ifaddr) } return ipAddress } }

Uso:

UIDevice.current.ipAddress()


Para Swift en Mac - Swift 4: de esta manera también puede encontrar la ip desde Wifi (no solo Ethernet)

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) } else if name == "en1" { // 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(1), NI_NUMERICHOST) address = String(cString: hostname) } } } freeifaddrs(ifaddr) return address }


Puede buscar la dirección IP usando el siguiente código:

Nota: He utilizado la accesibilidad para que capture una nueva dirección IP en caso de que WiFi se cambie a otra.

  1. En el archivo Podfile

    pod ''ReachabilitySwift'' y luego install pod

  2. En el archivo AppDelegate.swift import ReachabilitySwift

    Nota: Si aparece un error que no pudo encontrar el módulo ReachabilitySwift, simplemente copie y pegue esto. ¡Funciona!

  3. Función didFinishLaunchingOptions

    NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged), name: ReachabilityChangedNotification, object: reachability) do{ try reachability.startNotifier() } catch { print("could not start reachability notifier") }

  4. Luego copie y pegue el siguiente código en el archivo AppDelegate

    func reachabilityChanged(note: NSNotification) { let reachability = note.object as! Reachability if reachability.isReachable { if reachability.isReachableViaWiFi { print("Reachable via WiFi") } else { print("Reachable via Cellular") } setIPAddress() } else { ipAddress = "" // No IP captures print("Network not reachable") } } func setIPAddress() { if let addr = self.getWiFiAddress() { print("ipAddress : /(addr)") ipAddress = addr } else { ipAddress = "" // No IP captures print("No WiFi address") } } // 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 addr = interface.ifa_addr.pointee var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) getnameinfo(&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 }

  5. Agregue esto en el archivo Bridging-Header #include<ifaddrs.h>

    En caso de que no tenga este archivo, puede crearlo. Verifique este enlace

6)

func applicationWillEnterForeground(_ application: UIApplication) { // Post notification NotificationCenter.default.post(name: ReachabilityChangedNotification, object: reachability) // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. }

  1. Si desea eliminar observador, entonces:

    reachability.stopNotifier() NSNotificationCenter.defaultCenter().removeObserver(self,name: ReachabilityChangedNotification,object: reachability)


Según varios hilos SO (por ejemplo, ¿qué significa exactamente el nombre de la interfaz de red iOS?

Su código (que parece ser lo que respondí en Cómo obtener la dirección IP en swift :) recupera una lista de las direcciones IP de todas las interfaces de red en ejecución. Se puede modificar fácilmente para devolver solo la dirección IP de la interfaz "en0", y en realidad eso es lo que originalmente había respondido en ese hilo (y esto es solo una traducción rápida de la respuesta a cómo obtener la dirección IP del iPhone mediante programación ):

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

Uso:

if let addr = getWiFiAddress() { print(addr) } else { print("No WiFi address") }

Actualización para Swift 3: además de adoptar el código para los muchos cambios en Swift 3 , la iteración en todas las interfaces ahora puede usar la nueva función de sequence() generalizada sequence() :

NO olvide agregar #include <ifaddrs.h> en su encabezado de puente

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

Para aquellos de ustedes que vinieron buscando más que la IP WIFI, podrían modificar este código un poco

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

Entonces también tenemos acceso a la IP celular.

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

Y

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


Si solo desea una respuesta IPv4 como salida, simplemente modifique la solución de Martin R.

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) { // **ipv6 committed if addrFamily == UInt8(AF_INET){ // 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 }

Uso:

if let addr = getWiFiAddress() { print(addr) } else { print("No WiFi address") }


Todas las respuestas aquí dan solo la dirección IP para wifi y no por cable o celular. El siguiente fragmento se puede utilizar para la caja wifi / cableada / celular:

func getIPAddressForCellOrWireless()-> String? { let WIFI_IF : [String] = ["en0"] let KNOWN_WIRED_IFS : [String] = ["en2", "en3", "en4"] let KNOWN_CELL_IFS : [String] = ["pdp_ip0","pdp_ip1","pdp_ip2","pdp_ip3"] var addresses : [String : String] = ["wireless":"", "wired":"", "cell":""] var address: String? var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil if getifaddrs(&ifaddr) == 0 { var ptr = ifaddr while ptr != nil { defer { ptr = ptr?.pointee.ifa_next } // memory has been renamed to pointee in swift 3 so changed memory to pointee let interface = ptr?.pointee let addrFamily = interface?.ifa_addr.pointee.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { if let name: String = String(cString: (interface?.ifa_name)!), (WIFI_IF.contains(name) || KNOWN_WIRED_IFS.contains(name) || KNOWN_CELL_IFS.contains(name)) { // String.fromCString() is deprecated in Swift 3. So use the following code inorder to get the exact IP Address. 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) if WIFI_IF.contains(name){ addresses["wireless"] = address }else if KNOWN_WIRED_IFS.contains(name){ addresses["wired"] = address }else if KNOWN_CELL_IFS.contains(name){ addresses["cell"] = address } } } } } freeifaddrs(ifaddr) var ipAddressString : String? let wirelessString = addresses["wireless"] let wiredString = addresses["wired"] let cellString = addresses["cell"] if let wirelessString = wirelessString, wirelessString.count > 0{ ipAddressString = wirelessString }else if let wiredString = wiredString, wiredString.count > 0{ ipAddressString = wiredString }else if let cellString = cellString, cellString.count > 0{ ipAddressString = cellString } return ipAddressString }


Para obtener IPAddress para wifi, cableado y celular (swift 5)

func getIPAddress() -> String { var address: String? var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil if getifaddrs(&ifaddr) == 0 { var ptr = ifaddr while ptr != nil { defer { ptr = ptr?.pointee.ifa_next } let interface = ptr?.pointee let addrFamily = interface?.ifa_addr.pointee.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { // wifi = ["en0"] // wired = ["en2", "en3", "en4"] // cellular = ["pdp_ip0","pdp_ip1","pdp_ip2","pdp_ip3"] let name: String = String(cString: (interface!.ifa_name)) if name == "en0" || name == "en2" || name == "en3" || name == "en4" || name == "pdp_ip0" || name == "pdp_ip1" || name == "pdp_ip2" || name == "pdp_ip3" { 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 ?? "" }

Cómo utilizar

let strIPAddress : String = self.getIPAddress() print("IPAddress :: /(strIPAddress)")

Nota: Agregue esto a continuación en el archivo Bridging-Header de su proyecto

#include<ifaddrs.h>


Swift 4 - Obtenga la dirección IP del dispositivo:

Agregue #include<ifaddrs.h> en su encabezado de puente.

Este es el marco necesario para obtener la dirección IP.

class func getIPAddress() -> String? { var address: String? var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil if getifaddrs(&ifaddr) == 0 { var ptr = ifaddr while ptr != nil { defer { ptr = ptr?.pointee.ifa_next } let interface = ptr?.pointee let addrFamily = interface?.ifa_addr.pointee.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { if let name: String = String(cString: (interface?.ifa_name)!), name == "en0" { 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 }


func getIPAddress() -> String { var address: String = "error" var interfaces: ifaddrs? = nil var temp_addr: ifaddrs? = nil var success: Int = 0 // retrieve the current interfaces - returns 0 on success success = getifaddrs(interfaces) if success == 0 { // Loop through linked list of interfaces temp_addr = interfaces while temp_addr != nil { if temp_addr?.ifa_addr?.sa_family == AF_INET { // Check if interface is en0 which is the wifi connection on the iPhone if (String(utf8String: temp_addr?.ifa_name) == "en0") { // Get NSString from C String address = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr)) } } temp_addr = temp_addr?.ifa_next } } // Free memory freeifaddrs(interfaces) return address }