Swift - デバイスのWIFI IPアドレスの取得
質問
私は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 }
関連
-
[解決済み] Objective-Cで、ある文字列が他の文字列を含んでいるかどうかを調べるにはどうすればよいですか?
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] 文字列の長さを取得する
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] Swiftの@selector()?
-
[解決済み] SwiftでUIAlertViewを作成するにはどうしたらいいですか?
-
[解決済み] Swiftを使用してアプリのバージョンとビルド番号を取得するにはどうすればよいですか?
-
[解決済み] ぼかしの入ったオーバーレイビューの作成
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[iOS]コンパイルエラー:ld: アーキテクチャ x86_64 のシンボルが見つかりません。
-
[解決済み] キーボードがあるときに、UITextFieldを編集開始時に上に移動させるには?
-
[解決済み] Xcode 12、iOS Simulator用にビルドしても、iOS用にビルドされたオブジェクトファイルでは、アーキテクチャ「arm64」用にリンクされます。
-
[解決済み] Xcode 6のバグ:Interface Builderファイル内の不明なクラス
-
[解決済み] iOSシミュレータでスクリーンショットを撮る
-
[解決済み] UIButtonのタイトルを左揃えにするにはどうしたらよいですか?
-
[解決済み] アプリのプレビュー用にiOSシミュレータのビデオをキャプチャー
-
[解決済み] UITableView - トップにスクロールする
-
[解決済み] ファイルはユニバーサル(3スライス)ですが、iOSの静的ライブラリのための(n)ARMv7-sスライスエラーが含まれていない、どうにかして回避するには?
-
[解決済み] iOS 11、Apple TV 4Kなどを搭載したXcode 9でワイヤレスデバッグを行う方法とは?