【iOS × watchOS】iPhoneアプリと連携できるApple Watchアプリを開発しよう!

若い人からご年配の方まで装着率が増加傾向にあるスマートウォッチ。使用率を見るとApple Watchユーザーが圧倒的に数を占めています。

そんなApple Watchで利用しているアプリもiOSアプリ同様に開発することが可能になっており、Apple Watch単体で動作するアプリやiPhoneと連携してデータをやり取りすることができるアプリも実現できます。

今回はApple Watchアプリを開発してみたい方をターゲットに「iPhoneと連携した簡単なToDoアプリ」を開発する流れとApple Watchアプリ開発のポイントなどをまとめていきたいと思います。

 

 

◇ こんな人に読んでほしい!

  • iOSアプリは開発したことがある
  • watchOSアプリは開発したことがない
  • iOSとwatchOSアプリがどのようにデータをやり取りするか知りたい
  • watchOSアプリでのポイントや注意点を知りたい

iOSと連携したApple Watchアプリを開発する流れ

iPhoneと連携した簡単なToDoアプリ」を開発する流れの中でiOSとwatchOSが連携する部分の肝となる実装を見ていきます。

 

◇開発する流れ(iOS ↔︎ watchOS間の実装)

  1. iOSとwatchOSをターゲットに含んだプロジェクトを作成
  2. iOS側にwatchOS側と通信するためのクラスを作成
  3. watchOS側にiOS側と通信するためのクラスを作成
  4. データを送受信する部分の実装

 

◇アプリ概要 & 機能一覧

  • ローカル保存はCore Dataを使用する
  • iOS側からToDoタスクの追加と削除、タスク完了フラグの操作が行える
  • watchOS側からタスク完了フラグを操作可能
  • watchOS側にも常に最新データをローカル保存

 

今回は記事の都合上「iOS↔︎watchOS間のデータ通信部分の実装方法」にフォーカスを当てて紹介していきます。Core Dataを使用したローカル保存やUIの実装などは割愛させていただきましたが、GitHubにプロジェクト全体のソースコードをあげてありますのでプルしてお試しいただければと思います。

GitHub:DemoApp

1. iOSとwatchOSをターゲットに含んだプロジェクトを作成

iOSと連携したwatchOSアプリを開発するためのプロジェクトを作成します。Xcodeを起動させてwatchOS」タブの中の「App」をクリックします。

XcodeからiOS/watchOSターゲットを追加する様子

今回はiOSと連携したアプリを開発したいのでWatch App with New Companion iOS App」にチェックを入れて次へ進みます。この際にApple Watch単体で動作するアプリを開発したい場合は「Watch-only App」にチェックを入れて進みます。違いは自動でiOSターゲットが生成されるかどうかです。また後からiOSターゲットやwatchOSターゲットを追加することも可能になっています。

XcodeからiOS/watchOSターゲットを追加する様子

プロジェクトの作成が完了すると以下のように「iOSターゲット:WatchToDoApp」と「watchOSターゲット:WatchToDoApp Apple Watch」が作られていることを確認できます。

Xcode内のプロジェクト階層

2. iOS側にwatchOS側と通信するためのクラスを作成

iOS側からwatchOS側と通信を行うためのクラスを実装します。肝になるのはWCSessionクラスです。WCSession.activate()を実行することでwatchOSアプリと連携するためのセッションを有効にすることができます。

watchOSとの通信状態はWCSessionDelegate経由で検知することが可能です。Apple Watchに連携アプリがインストールされているかどうかや通信可能状態(スリープ状態ではない)かどうかなど通信を行うために必要な状態の変化を検知することが可能です。

このクラスに後でwatchOSにデータを送信する処理と受信する処理を追加していきます。

 

3. watchOS側にiOS側と通信するためのクラスを作成

watchOS側にもiOSと通信を行うためのクラスを実装します。実装はiOS側に実装したものとほとんど同じ様な形で実装することができます。

 

4. データを送受信する部分の実装

ここまででiOSとwatchOS間の通信を行うための土台を実装しました。ここからは実際にiOS↔︎watchOS間でデータを送受信する仕組みを実装していきます。

 

◇送受信するためのメソッド

データの送信を行うのはsendMessageメソッドです。(他にも色々あり用途が異なります。)これはiOS/watchOS関係なく同じメソッドを使用することができます。データは辞書[String:Any]形式でのみ送信できます。また送信が成功したかどうかはreplyHandlerで受け取ることが可能で、不要であればreplyHandlerには空のクロージャーを渡します。

 

◇データ送信側

sendMessageメソッドで送信されたデータはWCSessionDelegateの以下のデリゲートメソッドで受信することができます。replyHandler(message)を呼び出せば送信側で送信結果を参照することができます。

 

◇データ受信側

 


iOS → watchOSへデータを送信する

ここでは「iOS側で保存されたローカルデータ(ToDoタスク)をwatchOS側へ送信してwatchOS側にも保存する処理」を実装します。

実際に先ほどのクラスに実装してみます。WatchCommunicationManagerには以下のようにデータを送信するメソッドを追加します。送信する独自クラスをJSONに変換してから辞書形式に詰めていきます。

iOSCommunicationManagerにはデータを受信するデリゲートメソッドを用意し、受け取った辞書からキーを頼りにJSONを抜き出し、独自クラスへ変換していきます。

 


watchOS → iOSへデータを送信する

次は「watchOS側からToDoタスクの完了フラグを操作したイベントを送信し、iOS側のローカルデータを更新する処理」を実装します。

iOSCommunicationManagerからは更新対象のデータのIDを送信します。

 

WatchCommunicationManagerではwatchOSから送信されたIDを元に対象データの完了フラグを切り替えます。

これでwatchOSとiOS間のデータの送受信部分の実装は完了になります。

Core DataのエンティティをJSONで変換して送受信するためには少しNSManagedObjectContextの取り扱いに注意が必要です。GithHubに全コードを公開しているので参考にしてみてください。

GitHub:DemoApp

watchOSアプリ開発で気をつけること

  • Swift UIでの開発
  • iOSとwatchOSは通信可能状態が細かく変換する
  • 送受信できるデータは辞書形式[String: Any]でプリミティブ型のみ
  • データを送信するメソッドは一部シミュレーターでは動作しない

Swift UIでの開発

watchOS側の開発は以前はStoryboardを使用した開発でしたが、watchOS 7以降よりStoryboardを使用したUI設計は非推奨となりSwift UIでの実装が推奨される様になりました。

まだまだStoryboardでの案件も多い中でSwift UIに切り替える良いタイミングにもなるかと思います。

もちろんiOS側をStoryboardで、watchOS側もSwfit UIで開発することも可能になっています。

iOSとwatchOSは通信可能状態が細かく変換する

Apple Watchは秒数経過や腕を下ろすなど特定の操作でスリープモード(画面が暗くなる)に変化します。スリープモードに入るとiOSアプリとのデータの送受信も行えなくなるので先ほどのsendMessageでは送信したはずのデータがwatchOS側で取得できないといったことが発生します。

それを防ぐためには細かく通信可能状態をチェックしたり、スリープモード中でもデータを送信できるtransferUserInfoメソッドなどを使用したりして両OSのライフサイクルを考慮した設計をする必要があります。

送受信できるデータは辞書形式[String: Any]でプリミティブ型のみ

両OS間で送信できるデータは辞書形式[String: Any]のみとなっています。Anyなので独自のクラスなども渡せてしまいますが、それは期待通りに動作しません。

sendMessageなどのAny側に含まることができるのはプリミティブ型(StringやIntなど)限定と定義のコメントに記載されています。

公式:Property List Types and Objects

そのため独自のクラスなどを渡したい場合はJSONに変換して送信し、受信側でデコードすることで期待通りの実装を叶えることが可能です。

データを送信するメソッドは一部シミュレーターでは動作しない

WatchConnectivityフレームワークに定義されている両OS間でデータを送受信するメソッドは以下の4種類です。

 

  • sendMessage・・・データを送信 / 受信されない場合は無効
  • transferUserInfo・・・データを送信 / 受信されない場合はキューにスタック
  • updateApplicationContext・・・データを送信 / 受信されない場合は更新して保管
  • transferFile・・・ファイルを送信 / 受信されない場合はキューにスタック

 

受け取り側の状況によりキューに貯めることができるメソッドもあり、データの送信漏れが起きない様な実装をすることが可能になっています。

注意点としてはtransferUserInfoとtransferFileはシミュレーターでは動作しないので動作確認には実機を用いる必要があります。

終わりに

watchOSアプリの開発はこれまでのiOSアプリ開発とあまり変化がなく実装できることがわかりました。

データの通信絡みで多少癖はあるものの、用意されているAPIも直感的でわかりやすいものが多い印象です。既存のiOSプロジェクトにあとからwatchOSプロジェクトを追加することも可能になっているので既存のiOSアプリに追加して開発して見るのも楽しそうですね。

この記事が少しでもwatchOSアプリ開発に興味を持つきっかけになると幸いです。

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

ソニックムーブは一緒に働くメンバーを募集しています

Wantedlyには具体的な業務内容のほかメンバーインタビューも掲載しております。ぜひご覧ください。

    あわせて読みたい記事