Watchアプリを開発しよう!tshibuya2024.08.30アプリ若い人からご年配の方まで装着率が増加傾向にあるスマートウォッチ。Watchユーザーが圧倒的に数を占めています。Watch単体で動作するアプリやiPhoneと連携してデータをやり取りすることができるアプリも実現できます。Watchアプリ開発のポイントなどをまとめていきたいと思います。Watchアプリを開発する流れ「iPhoneと連携した簡単なToDoアプリ」を開発する流れの中でiOSとwatchOSが連携する部分の肝となる実装を見ていきます。今回は記事の都合上「iOS↔︎watchOS間のデータ通信部分の実装方法」にフォーカスを当てて紹介していきます。Dataを使用したローカル保存やUIの実装などは割愛させていただきましたが、GitHubにプロジェクト全体のソースコードをあげてありますのでプルしてお試しいただければと思います。iOSとwatchOSをターゲットに含んだプロジェクトを作成iOSと連携したwatchOSアプリを開発するためのプロジェクトを作成します。Xcodeを起動させて「watchOS」タブの中の「App」をクリックします。App」にチェックを入れて次へ進みます。App」にチェックを入れて進みます。違いは自動でiOSターゲットが生成されるかどうかです。後からiOSターゲットやwatchOSターゲットを追加することも可能になっています。Watch」が作られていることを確認できます。iOS側にwatchOS側と通信するためのクラスを作成iOS側からwatchOS側と通信を行うためのクラスを実装します。肝になるのはWCSessionクラスです。WCSession.activate()を実行することでwatchOSアプリと連携するためのセッションを有効にすることができます。watchOSとの通信状態はWCSessionDelegate経由で検知することが可能です。Watchに連携アプリがインストールされているかどうかや通信可能状態(スリープ状態ではない)かどうかなど通信を行うために必要な状態の変化を検知することが可能です。このクラスに後でwatchOSにデータを送信する処理と受信する処理を追加していきます。watchOS側にiOS側と通信するためのクラスを作成watchOS側にもiOSと通信を行うためのクラスを実装します。実装はiOS側に実装したものとほとんど同じ様な形で実装することができます。データを送受信する部分の実装ここまででiOSとwatchOS間の通信を行うための土台を実装しました。ここからは実際にiOS↔︎watchOS間でデータを送受信する仕組みを実装していきます。nil)データの送信を行うのはsendMessageメソッドです。(他にも色々あり用途が異なります。)これはiOS/watchOS関係なく同じメソッドを使用することができます。データは辞書[String:Any]形式でのみ送信できます。送信が成功したかどうかはreplyHandlerで受け取ることが可能で、不要であればreplyHandlerには空のクロージャーを渡します。inprint(error)}sendMessageメソッドで送信されたデータはWCSessionDelegateの以下のデリゲートメソッドで受信することができます。replyHandler(message)を呼び出せば送信側で送信結果を参照することができます。watchOSへデータを送信するここでは「iOS側で保存されたローカルデータ(ToDoタスク)をwatchOS側へ送信してwatchOS側にも保存する処理」を実装します。実際に先ほどのクラスに実装してみます。WatchCommunicationManagerには以下のようにデータを送信するメソッドを追加します。送信する独自クラスをJSONに変換してから辞書形式に詰めていきます。})}iOSCommunicationManagerにはデータを受信するデリゲートメソッドを用意し、受け取った辞書からキーを頼りにJSONを抜き出し、独自クラスへ変換していきます。iOSへデータを送信する次は「watchOS側からToDoタスクの完了フラグを操作したイベントを送信し、iOS側のローカルデータを更新する処理」を実装します。iOSCommunicationManagerからは更新対象のデータのIDを送信します。})}WatchCommunicationManagerではwatchOSから送信されたIDを元に対象データの完了フラグを切り替えます。!work.flagCoreDataRepository.saveContext()self._isUptate.send(true)}}これでwatchOSとiOS間のデータの送受信部分の実装は完了になります。DataのエンティティをJSONで変換して送受信するためには少しNSManagedObjectContextの取り扱いに注意が必要です。GithHubに全コードを公開しているので参考にしてみてください。UIでの実装が推奨される様になりました。UIに切り替える良いタイミングにもなるかと思います。UIで開発することも可能になっています。Watchは秒数経過や腕を下ろすなど特定の操作でスリープモード(画面が暗くなる)に変化します。スリープモードに入るとiOSアプリとのデータの送受信も行えなくなるので先ほどのsendMessageでは送信したはずのデータがwatchOS側で取得できないといったことが発生します。それを防ぐためには細かく通信可能状態をチェックしたり、スリープモード中でもデータを送信できるtransferUserInfoメソッドなどを使用したりして両OSのライフサイクルを考慮した設計をする必要があります。Any]のみとなっています。Anyなので独自のクラスなども渡せてしまいますが、それは期待通りに動作しません。sendMessageなどのAny側に含まることができるのはプリミティブ型(StringやIntなど)限定と定義のコメントに記載されています。クライアントはこのメソッドを使用して、対応するアプリにメッセージを送信できます。ブロックを渡す必要があります。ブロックがエラーで呼び出されます。メッセージは送信アプリの実行中にのみ送信できます。メッセージが送信される前に送信側アプリが終了すると、送信は失敗します。タイプのみを受け入れることができます。クライアントはこのメソッドを使用して、対応するアプリにメッセージを送信できます。ブロックを渡す必要があります。ブロックがエラーで呼び出されます。メッセージは送信アプリの実行中にのみ送信できます。メッセージが送信される前に送信側アプリが終了すると、送信は失敗します。タイプのみを受け入れることができます。nil)そのため独自のクラスなどを渡したい場合はJSONに変換して送信し、受信側でデコードすることで期待通りの実装を叶えることが可能です。データを送信するメソッドは一部シミュレーターでは動作しないWatchConnectivityフレームワークに定義されている両OS間でデータを送受信するメソッドは以下の4種類です。受信されない場合はキューにスタック受け取り側の状況によりキューに貯めることができるメソッドもあり、データの送信漏れが起きない様な実装をすることが可能になっています。注意点としてはtransferUserInfoとtransferFileはシミュレーターでは動作しないので動作確認には実機を用いる必要があります。終わりにwatchOSアプリの開発はこれまでのiOSアプリ開発とあまり変化がなく実装できることがわかりました。データの通信絡みで多少癖はあるものの、用意されているAPIも直感的でわかりやすいものが多い印象です。既存のiOSプロジェクトにあとからwatchOSプロジェクトを追加することも可能になっているので既存のiOSアプリに追加して開発して見るのも楽しそうですね。この記事が少しでもwatchOSアプリ開発に興味を持つきっかけになると幸いです。ご覧いただきありがとうございました。ソニックムーブは一緒に働くメンバーを募集していますWantedlyには具体的な業務内容のほかメンバーインタビューも掲載しております。SHARE記事作成者の紹介tshibuyaアプリ開発部アプリユニット所属。甘いものには目がなく、毎日チョコレートを食べている。公式XWeb制作・アプリ開発に関する、UI/UX情報、エンジニア向け情報、イラストテクニックをお届けしています。