SwiftでiOSデバイスのIPアドレスを取得する必要があります。これは、これに関する他の質問の重複ではありません! WiFi IPアドレスがない場合、WiFi IPアドレスのみを取得する必要があります-それを処理する必要があります。 Stack Overflowにはいくつかの質問がありますが、IPアドレスを返す関数のみがあります。例(from 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
}
ここでは、モバイルインターネットからのアドレス(私が思う)と必要なWiFiアドレスの2つの値を取得します。 WiFi IPアドレスのみを取得する他の方法はありますか?
いくつかのSOスレッド(例: iOSネットワークインターフェース名とはどういう意味ですか?pdp_ipとは何ですか? )によれば、iOSデバイスのWiFiインターフェースは常に "en0"という名前になります。
あなたのコード( でIPアドレスを取得する方法Swift で答えたようです):allのIPアドレスのリストを取得します実行中のネットワークインターフェイス。 "en0"インターフェースのIPアドレスのみを返すように簡単に変更できます。実際、それはそのスレッドでoriginallyが応答したものです(これは単なる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")
}
Swift3:の更新:Swift3での多くの変更 にコードを採用することに加えて、すべてのインターフェースの繰り返しで新しい一般化された 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 }
ブリッジングヘッダーを作成し、#include <ifaddrs.h>
を含めます。
次に、このメソッドを書きます
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
}
var arr : NSArray = self.getIFAddresses()
のようにviewControllerでこのメソッドを呼び出すと、コンソールで次のような完璧な応答が得られます。
IP :( "10.0.0.94")
この配列から、どこにでもアクセスできます。それが役に立てば幸い
Swift 4-デバイスのIPアドレスを取得:
ブリッジングヘッダーに#include<ifaddrs.h>
を追加します。
これは、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
}
Swift 4.2 UIDevice
拡張機能は、強制的な展開を回避し、セルラーIPアドレスと有線IPアドレスをサポートします。
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
}
}
使用法:
UIDevice.current.ipAddress()
wifi、有線、およびセルラーのIPAddressを取得するには(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 ?? ""
}
使用方法
let strIPAddress : String = self.getIPAddress()
print("IPAddress :: \(strIPAddress)")
注:プロジェクトのBridging-Headerファイルに以下を追加
#include<ifaddrs.h>
以下のコードを使用してIPアドレスを取得できます。
注:WiFiが別のIPアドレスに変更された場合に新しいIPアドレスをキャプチャするように、到達可能性を使用しました。
Podfile
ファイル
pod 'ReachabilitySwift'
、次にinstall pod
AppDelegate.Swift
ファイルimport ReachabilitySwift
注:ReachabilitySwiftモジュールが見つかりませんでしたというエラーが表示された場合は、これをコピーして貼り付けてください。できます!
didFinishLaunchingOptions
関数
NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged), name: ReachabilityChangedNotification, object: reachability)
do{
try reachability.startNotifier()
}
catch {
print("could not start reachability notifier")
}
次に、以下のコードをコピーして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
}
これをBridging-Headerファイルに追加します#include<ifaddrs.h>
このファイルがない場合は、作成できます このリンクを確認してください
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.
}
オブザーバーを削除する場合:
reachability.stopNotifier()
NSNotificationCenter.defaultCenter().removeObserver(self,name: ReachabilityChangedNotification,object: reachability)
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
}
ここでのすべての答えは、有線または携帯電話ではなく、wifiのIPアドレスのみを提供します。次のスニペットは、wifi /有線/携帯電話の場合に使用できます。
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
}
出力としてIPv4応答のみが必要な場合は、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
}
使用法:
if let addr = getWiFiAddress() {
print(addr)
} else {
print("No WiFi address")
}
MacのSwiftの場合-Swift 4:この方法で、WifiからIPを見つけることもできます(イーサネットだけでなく)
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
}