LionHeart SD BLOG

株式会社ライオンハート システムデザインの技術ブログ

iOSとWatchOSの双方向データ送受信(Watch Connectivity)を試してみる

こんにちは、株式会社ライオンハートの鵜飼です。

Xcode 7になり、実機検証時のDeveloperプログラム登録が必須ではなくなったため、アプリ開発をする際の障壁が一つ無くなり、手軽に試すことが出来るようになりましたね。

そこで、試しにiOS9+WatchOSでの実機検証を兼ねて、簡単なSwiftのプログラムを試してみました。

試してみたもの

WatchOS2から、iOS <-> WatchOSの双方向のデータ通信が出来るようになったそうなので、その辺りの処理を試してみました。
ちなみに、Watch Connectivityという名前だそうです。

また、送受信の方法については色々な種類があるそうなのですが、今回は使い勝手が良さそうなBackground transfers + Application Contextの方法を取っています。

下準備

まず、必要な処理を実行するためにはWatchConnectivityをimportし、classにWCSessionDelegateを指定します。
例えば、プロジェクトを作成した時に存在しているViewControllerに追加する場合はこんな感じです。

import WatchConnectivity

class ViewController: UIViewController, WCSessionDelegate {
    // ...
}

次にデータを送受信するために、WCSessionを有効にします。

if WCSession.isSupported() {
    let session = WCSession.defaultSession()
    session.delegate = self
    session.activateSession()
}

コレらは、iOS端末、WatchOS端末双方にて設定をしてください。

データ送受信

下準備ができたらデータの送受信にとりかかります。

送信する側では、updateApplicationContextで送信したいデータを渡して実行します。
送信するデータは、[ string: AnyObject ]の型に指定する必要があります。

let applicationDict = [ "foo": "bar" ];

do {
    try WCSession.defaultSession().updateApplicationContext( applicationDict )
} catch {
    print( "Send Error" );
}

次に、受信する側の処理です。
受信する側では次のように記述します。

func session( session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject] ) {
    let foo = applicationContext["foo"] as! String
    
    dispatch_async( dispatch_get_main_queue() ) {
        print( foo ) // printed "bar"
    }
}

この処理は、iOS -> WatchOSだとしても、WatchOS -> iOSだとしても流れは変わりません。(変わりませんよね?)

課題点

しかし、現状これらの記述でまだ問題が出ています。

  • シミュレータだと正常に動作するが、実機で試すとiOS -> WatchOSでエラーが発生する
  • WatchOS -> iOSは動作する(なぜコッチだけOKなのかは謎)

もしかすると、updateApplicationContextはWatchOS -> iOSだけなのかなぁ…とか考えつつも、シミュレータで動くので謎が謎を呼んでいる状態です。

後日ためしてみると今度は動きました(プログラムの変更はなし)。
Paringが上手く行っていなかっただけかもしれません…うーん…。

雑感

以前のデベロッパープログラムが必須の頃に比べると、格段に実機テストがやりやすくなったのは確かなので、今後も色々と試していきたいですね。

参考