Skip to content

Instantly share code, notes, and snippets.

@treastrain
Last active March 11, 2022 02:52
Show Gist options
  • Save treastrain/9913abfc46125cc904a1ac984d4656f7 to your computer and use it in GitHub Desktop.
Save treastrain/9913abfc46125cc904a1ac984d4656f7 to your computer and use it in GitHub Desktop.
NWPathMonitor のサンプル
//
// NetworkPlaygroundApp.swift
// NetworkPlayground
//
// Created by treastrain / Tanaka Ryoga on 2021/09/28.
//
import SwiftUI
import Network
class NetworkMonitor: ObservableObject {
@Published var status = "Waiting..."
@Published var availableInterfaces = ""
@Published var gateways = ""
@Published var supportsIPv4 = ""
@Published var supportsIPv6 = ""
@Published var supportsDNS = ""
@Published var isConstrained = ""
@Published var isExpensive = ""
@Published var debugDescription = ""
@Published var localEndpoint = ""
@Published var remoteEndpoint = ""
@Published var unsatisfiedReason = ""
let monitor = NWPathMonitor()
func start() {
monitor.pathUpdateHandler = { path in
DispatchQueue.main.async {
self.status = "\(path.status)"
self.availableInterfaces = "\(path.availableInterfaces)"
self.gateways = "\(path.gateways)"
self.supportsIPv4 = "\(path.supportsIPv4)"
self.supportsIPv6 = "\(path.supportsIPv6)"
self.supportsDNS = "\(path.supportsDNS)"
self.isConstrained = "\(path.isConstrained)"
self.isExpensive = "\(path.isExpensive)"
self.debugDescription = "\(path.debugDescription)"
self.localEndpoint = "\(path.localEndpoint)"
self.remoteEndpoint = "\(path.remoteEndpoint)"
self.unsatisfiedReason = "\(path.unsatisfiedReason)"
}
print("--------------------")
print("status:", path.status)
print("availableInterfaces:", path.availableInterfaces)
print("gateways:", path.gateways)
print("supportsIPv4:", path.supportsIPv4)
print("supportsIPv6:", path.supportsIPv6)
print("supportsDNS:", path.supportsDNS)
print("isConstrained:", path.isConstrained)
print("isExpensive:", path.isExpensive)
print("debugDescription:", path.debugDescription)
print("localEndpoint:", path.localEndpoint)
print("remoteEndpoint:", path.remoteEndpoint)
print("unsatisfiedReason:", path.unsatisfiedReason)
print("--------------------")
}
monitor.start(queue: .global(qos: .background))
}
func cancel() {
monitor.cancel()
}
}
@main
struct NetworkPlaygroundApp: App {
@ObservedObject var networkMonitor = NetworkMonitor()
init() {
networkMonitor.start()
}
var body: some Scene {
WindowGroup {
VStack(alignment: .leading) {
Group {
Text("status: ") + Text(networkMonitor.status)
Text("availableInterfaces: ") + Text(networkMonitor.availableInterfaces)
Text("gateways: ") + Text(networkMonitor.gateways)
Text("supportsIPv4: ") + Text(networkMonitor.supportsIPv4)
Text("supportsIPv6: ") + Text(networkMonitor.supportsIPv6)
Text("supportsDNS: ") + Text(networkMonitor.supportsDNS)
Text("isConstrained: ") + Text(networkMonitor.isConstrained)
Text("isExpensive: ") + Text(networkMonitor.isExpensive)
}
Group {
Text("debugDescription: ") + Text(networkMonitor.debugDescription)
Text("localEndpoint: ") + Text(networkMonitor.localEndpoint)
Text("remoteEndpoint: ") + Text(networkMonitor.remoteEndpoint)
Text("unsatisfiedReason: ") + Text(networkMonitor.unsatisfiedReason)
}
}
.font(.system(.body, design: .monospaced))
}
}
}
/**
# 以下、いろんな端末・環境で動かしてみた例
## iPhone 13 Pro、機内モードにより Wi-Fi・Cellular・Bluetooth オフ
--------------------
status: unsatisfied
availableInterfaces: []
gateways: []
supportsIPv4: false
supportsIPv6: false
supportsDNS: false
isConstrained: false
isExpensive: false
debugDescription: unsatisfied (No network route)
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
## iPhone 13 Pro、Cellular (5G)、Wi-Fi (IPv6)
`availableInterfaces: [en0, pdp_ip0]` ということで、Wi-Fi と Cellular が使えることがわかる
一度 `en0, ipv6, dns` になり、その後 IPv4 over IPv6 になるところが確認できる
--------------------
status: satisfied
availableInterfaces: [en0, pdp_ip0]
gateways: [fe80::fab7:97ff:fef8:50dc%en0%en0.0]
supportsIPv4: false
supportsIPv6: true
supportsDNS: true
isConstrained: false
isExpensive: false
debugDescription: satisfied (Path is satisfied), interface: en0, ipv6, dns
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
--------------------
status: satisfied
availableInterfaces: [en0, pdp_ip0]
gateways: [192.168.10.1:0, fe80::fab7:97ff:fef8:50dc%en0%en0.0]
supportsIPv4: true
supportsIPv6: true
supportsDNS: true
isConstrained: false
isExpensive: false
debugDescription: satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
## iPhone 13 Pro、Cellular (5G)
`availableInterfaces: [pdp_ip0]` ということで、Cellular のみ使えることがわかる
`isExpensive: true` となっており、セルラー通信である可能性がみられる
--------------------
status: satisfied
availableInterfaces: [pdp_ip0]
gateways: [10.170.192.37:0, fe80::39cd:1f70:205:e71a%pdp_ip0%pdp_ip0.0]
supportsIPv4: true
supportsIPv6: true
supportsDNS: true
isConstrained: false
isExpensive: true
debugDescription: satisfied (Path is satisfied), interface: pdp_ip0[lte], ipv4, ipv6, dns, expensive
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
## iPad Air (4th gen. Wi-Fi モデル)、Wi-Fi (IPv6)
`availableInterfaces: [en0]` ということで、Wi-Fi のみ使えることがわかる
一度 `en0, ipv6, dns` になり、その後 IPv4 over IPv6 になるところが確認できる
--------------------
status: satisfied
availableInterfaces: [en0]
gateways: [fe80::fab7:97ff:fef8:50dc%en0%en0.0]
supportsIPv4: false
supportsIPv6: true
supportsDNS: true
isConstrained: false
isExpensive: false
debugDescription: satisfied (Path is satisfied), interface: en0, ipv6, dns
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
--------------------
status: satisfied
availableInterfaces: [en0]
gateways: [192.168.10.1:0, fe80::fab7:97ff:fef8:50dc%en0%en0.0]
supportsIPv4: true
supportsIPv6: true
supportsDNS: true
isConstrained: false
isExpensive: false
debugDescription: satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
## iPad Air (4th gen. Wi-Fi モデル)、Ethernet(有線LAN)接続
`availableInterfaces: [en3]` ということで、Ethernet(有線LAN)接続であることがわかる
--------------------
status: satisfied
availableInterfaces: [en3]
gateways: [192.168.10.1:0, fe80::fab7:97ff:fef8:50dc%en0%en3.0]
supportsIPv4: true
supportsIPv6: true
supportsDNS: true
isConstrained: false
isExpensive: false
debugDescription: satisfied (Path is satisfied), interface: en3, ipv4, ipv6, dns
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
## iPad Air (4th gen. Wi-Fi モデル)、Ethernet(有線LAN)接続されていて、Wi-Fi にも接続されている
`availableInterfaces: [en3, en0]` ということで、Ethernet(有線LAN)と Wi-Fi の両方で接続でされていることがわかる
--------------------
status: satisfied
availableInterfaces: [en3, en0]
gateways: [192.168.10.1:0, fe80::fab7:97ff:fef8:50dc%en0%en3.0]
supportsIPv4: true
supportsIPv6: true
supportsDNS: true
isConstrained: false
isExpensive: false
debugDescription: satisfied (Path is satisfied), interface: en3, ipv4, ipv6, dns
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
## iPad Air (4th gen. Wi-Fi モデル)、Wi-Fi 経由で Cellular (5G) に接続された iPhone 13 Pro にテザリングして接続
`isConstrained: true` ということで、Low Data Mode(省データモード)が使われていることがわかる
--------------------
status: satisfied
availableInterfaces: [en0]
gateways: [172.20.10.1:0, fe80::f465:a6ff:fef6:f764%en0%en0.0]
supportsIPv4: true
supportsIPv6: true
supportsDNS: true
isConstrained: true
isExpensive: false
debugDescription: satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns, constrained
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
## iPad Air (4th gen. Wi-Fi モデル)、Bluetooth 経由で Cellular (5G) に接続された iPhone 13 Pro にテザリングして接続
`isExpensive: true` となっており、Bluetooth 通信である可能性がみられる
--------------------
status: satisfied
availableInterfaces: [en4]
gateways: [172.20.10.1:0, fe80::f465:a6ff:fef6:f764%en0%en4.0]
supportsIPv4: true
supportsIPv6: true
supportsDNS: true
isConstrained: false
isExpensive: true
debugDescription: satisfied (Path is satisfied), interface: en4, ipv4, ipv6, dns, expensive
localEndpoint: nil
remoteEndpoint: nil
unsatisfiedReason: notAvailable
--------------------
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment