【Swift】Reachabilityでネットワークの変化を監視する方法!

この記事からわかること

  • SwiftライブラリReachability導入方法使い方
  • ネットワーク接続状況変化監視する方法
  • whenReachable/whenUnreachableメソッドの使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

ネットワークの変化を監視する方法

ネットワークの接続状況を取得できるReachabilityでネットワークの接続状況の変化を監視するにはwhenReachableまたはwhenUnreachableメソッドを使用します。これらのメソッドでネットワークの接続状況の変化がおきた際に実行する処理を定義することができます。実際に監視を開始するにはstartNotifierメソッドを実行する必要があります。

class ViewController: UIViewController {
    
    private var reachability: Reachability? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        reachability = try? Reachability()
        reachability?.whenReachable = { reachability in
            print("接続したよ:\(reachability.connection)")
        }
        reachability?.whenUnreachable = { reachability in
            print("切断されたよ:\(reachability.connection)")
        }
        try? reachability?.startNotifier()
    }
}

元となっているのはReachabilityインスタンスなので当然ですがインスタンスが破棄されると監視も機能しなくなってしまいます。アプリ全体で監視させたい場合は以下のようにシングルトンのクラスなどを作成して実装すればOKです。

class NetworkStatusObservation {
    static var shared = NetworkStatusObservation()
    
    private var reachability: Reachability? = nil
    
    init(){
        reachability = try? Reachability()
    }
    
    public func startObserveNetworkStatus() {
        reachability?.whenReachable = { reachability in
            print("接続したよ:\(reachability.connection)")
        }
        reachability?.whenUnreachable = { reachability in
            print("切断されたよ:\(reachability.connection)")
        }
        try? reachability?.startNotifier()
    }
}

NotificationCenterで実装する

NotificationCenterを使用してネットワークの接続状況の変化を監視することも可能です。その場合はNSNotification.Name型にreachabilityChangedを指定します。

おすすめ記事:【Swift】NotificationCenterクラスの使い方!NSNotification.Name型の種類!

NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged), name: .reachabilityChanged, object: reachability)
@objc func reachabilityChanged() {
    print(reachability?.connection)
}

アプリ全体で使用しやすいようにクラスに切り出す場合は以下のような感じですかね!

class ViewController: UIViewController {
    
    private let networkStatusObservation = NetworkStatusObservation.shared
    private var cancellable: AnyCancellable?

    override func viewDidLoad() {
        super.viewDidLoad()
        
        cancellable = networkStatusObservation.networkStatusPublisher
            .sink { status in
                if status == .wifi {
                    print("ネットワークに接続されました")
                } else {
                    print("ネットワークに接続されていません")
                }
            }
    }
}

class NetworkStatusObservation {
    static let shared = NetworkStatusObservation()
    
    private let reachability: Reachability?
    private var cancellables = Set<AnyCancellable>()
    
    // Reachabilityの状態を通知するPublisher
    private let _networkStatusPublisher = PassthroughSubject<Reachability.Connection, Never>()
    // Reachabilityの状態を公開するPublisherを取得する
    public var networkStatusPublisher: AnyPublisher<Reachability.Connection, Never> {
        _networkStatusPublisher.eraseToAnyPublisher()
    }
    
    private init(){
        reachability = try? Reachability()
        
        // NotificationCenterでReachabilityの通知を購読する
        NotificationCenter.default.publisher(for: .reachabilityChanged, object: reachability)
            .compactMap { $0.object as? Reachability }
            .sink { reachability in
                self._networkStatusPublisher.send(reachability.connection)
            }
            .store(in: &cancellables)
        
        // Reachabilityの監視を開始する
        try? reachability?.startNotifier()
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index