ネットワーク通信されていない時は、「特定の表示を出したい」等があると思います。今回はApple標準のNWPathMonitor
を使用して、ネットワーク通信状態に応じてViewを変更するものを作っていきたいと思います。
環境
- Xcode 13.3
- iOS 15.5
作ったもの
ネットワーク状態が切れると画面が黒くなり、ネットワークが繋がると画面が青くなります。
NWPathMonitor
ネットワークの変更を監視して対応するために使用するオブザーバーです。func start(queue: DispatchQueue)
を使用することでパスの変更を監視することが出来ます。
今回はこのNWPathMonitor
を使用して、ネットワーク状態を監視するObservableObject
を作成していきます。
MonitoringNetworkState
MonitoringNetworkState
というネットワーク状態を監視するObservableObject
を作成します。
import Foundation
import Network
class MonitoringNetworkState: ObservableObject {
private let monitor = NWPathMonitor()
private let queue = DispatchQueue.global(qos: .background)
@Published var isConnected = false
init() {
monitor.start(queue: queue)
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
DispatchQueue.main.async {
self.isConnected = true
}
} else {
DispatchQueue.main.async {
self.isConnected = false
}
}
}
}
}
プロパティ
private let monitor = NWPathMonitor()
private let queue = DispatchQueue.global(qos: .background)
@Published var isConnected = false
ネットワーク状態を監視する為のNWPathMonitor()
とパス配信するイベントキューDispatchQueue.global(qos: .background)
を宣言します。
そして、ネットワーク状態をパブリッシュする為の変数@Published var isConnected
も用意します。
init
init() {
// パスモニターの開始
monitor.start(queue: queue)
// ネットワークパスが更新されたら行いたい処理を記述する
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
DispatchQueue.main.async {
self.isConnected = true
}
} else {
DispatchQueue.main.async {
self.isConnected = false
}
}
}
}
MonitoringNetworkState
の初期化時にパスモニターを開始し、ネットワークパスの更新を監視できるようにします。そして、パスのstatus
が.satisfied
(満足した)状態の場合はisConnected
がtrue
を返し、そうでない場合はfalse
を返すようにしています。
ContentView
あとは、MonitoringNetworkState.isConnected
の値を見て処理を切り分ければ完成です。
import SwiftUI
struct ContentView: View {
@EnvironmentObject var networkState: MonitoringNetworkState
var body: some View {
ZStack {
Rectangle()
.fill(networkState.isConnected ? .blue : .black)
Text(networkState.isConnected ? "Good connection" : "Bad connection")
.foregroundColor(.white)
}
}
}
先ほど、作成したObservableObject
のMonitoringNetworkState
をEnvironmentObject
として定義します。
あとは、networkState.isConnected
がtrue
なら背景色を青にして、false
なら黒に変更するようにしました。またテキストの内容もisConnected
の値によって変更するようにしました。
@main
上記ContentView
ではEnvironmentObject
を使用しているので、ContentView
呼出時に、environmentObject
Modifierを使用し、MonitoringNetworkState
を渡します。サブ階層にObservableObject
を提供する為には必要になります。
import SwiftUI
@main
struct MonitoringNetworkApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(MonitoringNetworkState())
}
}
}
これで完成です。
おわりに
ネットワーク通信状態をみるのにライブラリを使用せずとも標準のものを使用して監視できることが分かりました。NWPathMonitor
はSwiftUIで限られたものでも無いので、UIKit製のアプリでも同じように使うことが出来ます。またUIKitでも試してみたいと思います。
今回のコードはGitHubに置いております。
この記事が誰かの助けになれば幸いです。