【Swift/Apple Watch】通信可能(ペアリング)状態を観測/取得する方法!isReachableの変化

この記事からわかること

  • SwiftApple Watchアプリ開発する方法
  • iOSwatchOS通信可能状態であることを取得/観測するには?
  • WCSessionisReachableプロパティの使い方
  • WCSession counterpart app not installedとは?
  • WCSessionDelegateドsessionReachabilityDidChangeメソッドの役割

index

[open]

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

みんなの誕生日

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

posted withアプリーチ

環境

iOS↔︎watchOS間が通信可能状態であることを取得する方法

iOSアプリと連携した機能を実装しているwatchOSのアプリ両者がBluetoothでペアリングし通信可能状態であることをコードから取得するにはWCSessionクラスのisReachableプロパティを参照します。

WCSession.default.isReachable // true or false

公式リファレンス:isReachable

isReachableプロパティは正確にはアプリ同士がメッセージの送受信が利用できるかどうかを示す真偽値を返します。なのでこちらは両者のアプリが通信可能状態にあるかないかを識別する際に利用します。

ペアリングしているかを識別する

iPhoneとApple Watch自体がペアリング状態にあるかを取得したい場合はWCSessionクラスのisPairedプロパティを参照します。

WCSession.default.isPaired // true or false

公式リファレンス:isPaired

こちらはアプリではなく、デバイス同士が接続されていかを識別する際に利用します。

通信可能状態の変化を観測する

通信可能状態の変化を観測したい場合はWCSessionDelegatesessionReachabilityDidChange(_:)メソッドが変化した際に呼ばれるデリゲートメソッドです。例えばiOS側でwatchOS側と接続するためのクラスを実装していた場合は以下のようになります。


class WatchConnectViewModel: NSObject {

    override init() {
        self.session = .default
        super.init()
        if WCSession.isSupported() {
            self.session.delegate = self
            self.session.activate()
        }
    }
  
    func sessionReachabilityDidChange(_ session: WCSession) {
        print("状態が変化したよ")
        let isReachable = session.isReachable
        if isReachable {
            print("通信可能状態になりました")
        } else {
            print("通信が不可能な状態になりました")
        }
    }
}

ですがこのsessionReachabilityDidChange(_:)メソッドはiOSアプリを起動させたタイミングでは呼ばれずwatchOSアプリが停止した場合や再度復帰した場合に呼ばれるようです。呼ばれるタイミングは以下のような感じ

// watchOSアプリ起動
・・・呼ばれない 
// iOSアプリ起動
・・・呼ばれない 
[ペアリング/通信可能状態]
// watchOSアプリが停止
状態が変化したよ
通信が不可能な状態になりました
// watchOSアプリが再開
状態が変化したよ
通信可能状態になりました

通信状態に応じてUIを更新したい場合

通信可能状態をリアルタイムで観測しUIなどに反映させたい場合はObservableObjectを使って以下のように実装するのが良いのかも?しれません。isReachableの初回の更新はsession(_:,activationDidCompleteWith:, error:)メソッドでアクティベートになっているかを識別できるのでここで格納しています。

class WatchConnectViewModel: NSObject, ObservableObject {
    
    var session: WCSession
    @Published  var isReachable = false
    
    override init() {
        self.session = .default
        super.init()
        if WCSession.isSupported() {
            self.session.delegate = self
            self.session.activate()
        }
    }
}

extension WatchConnectViewModel: WCSessionDelegate {
    
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        if let error = error {
            print(error.localizedDescription)
        } else {
            print("セッション:アクティベート")
            isReachable = session.isReachable // true
        }
    }
    
    func sessionReachabilityDidChange(_ session: WCSession) {
        print("変化したよ")
        isReachable = session.isReachable
        if isReachable {
            print("通信可能")
        } else {
            print("通信が切断")
        }
    }
    
    func sessionDidBecomeInactive(_ session: WCSession) { }

    func sessionDidDeactivate(_ session: WCSession) { }
}

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

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

searchbox

スポンサー

ProFile

ame

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

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

New Article

index