本記事では、Watch Connectivityのとてもシンプルなサンプルコードを提供します。
公式のサンプルもありますが、こちらは全部入りとなっており、初めて見るとちょっと腰が引けてしまいます。そこで、本記事では余計な処理をすべて省いたとてもシンプルなコードを提供します。
目次
Watch Connectivityで作るサンプルアプリ
本記事で作るアプリは次のようなアプリです。

iPhoneとApple Watchの双方向で、sendMessagemメソッドを使ってメッセージの送受信を行います。
Watch Connectivityのサンプルを作る
さっそくコードを書いていきましょう。
プロジェクトの作成
まずはプロジェクトを作成します。iPhone側とApple Watch側の両方が必要なので、プロジェクトは「iOS App with watchOS App」を選択します。

iPhone側のコード
プロジェクトを作成したらiPhone側から作っていきましょう。ここでは2つのクラスを作成します。
- WatchConnector
- Apple Watchと通信するモジュールです
- ContextView
- デフォルトで作られるViewです。ここでUIを作ります。
WatchConnector
Apple Watchと通信するWatchConnectorクラスを作成します。短いので、先にすべてのコードをお見せします。
import UIKit import WatchConnectivity class WatchConnector: NSObject, ObservableObject, WCSessionDelegate { @Published var receivedMessage = "WATCH : 未受信" @Published var count = 0 override init() { super.init() if WCSession.isSupported() { WCSession.default.delegate = self WCSession.default.activate() } } func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { print("activationDidCompleteWith state= \(activationState.rawValue)") } func sessionDidBecomeInactive(_ session: WCSession) { print("sessionDidBecomeInactive") } func sessionDidDeactivate(_ session: WCSession) { print("sessionDidDeactivate") } func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { print("didReceiveMessage: \(message)") DispatchQueue.main.async { self.receivedMessage = "WATCH : \(message["WATCH_COUNT"] as! Int)" } } func send() { if WCSession.default.isReachable { count += 1 WCSession.default.sendMessage(["PHONE_COUNT" : count], replyHandler: nil) { error in print(error) } } } }
順番に説明していきますね。
まずはクラスの定義です。
class WatchConnector: NSObject, ObservableObject, WCSessionDelegate {
ObservableObjectはSwiftUIに受信したメッセージをバインドするためです。
WCSessionDelegateはWatch Connectivityが提供するプロトコルです。これを実装することで、Watch Connectivityのセッションのイベントや、送受信のイベント通知を受けることができます。
次に初期化を見ていきます。
override init() { super.init() if WCSession.isSupported() { WCSession.default.delegate = self WCSession.default.activate() } }
ここでは、Watch ConnectivityのセッションであるWCSessionをアクティベートしています。Watch Connectivityがサポートしていることを確認してから、デリゲートの指定とアクティベート化を行っています。
WCSEssionのデリゲートでは下記のメソッドが必須です。
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { print("activationDidCompleteWith state= \(activationState.rawValue)") } func sessionDidBecomeInactive(_ session: WCSession) { print("sessionDidBecomeInactive") } func sessionDidDeactivate(_ session: WCSession) { print("sessionDidDeactivate") }
それぞれ、アクティベート処理の完了・インアクティブ状態への遷移・ディアクティベイト状態への遷移を意味します。
WCSessionのデリゲートで、sendMessageでメッセージが送られてきた時の処理を見てみましょう。
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { print("didReceiveMessage: \(message)") DispatchQueue.main.async { self.receivedMessage = "WATCH : \(message["WATCH_COUNT"] as! Int)" } }
sendMessageでは辞書型のデータをメッセージとして送受信します。このアプリはApple Watchから”WATCH_COUNT”というキーで、Int型のカウンタが送られてくる仕様にしました。なので、ここではWATCH_COUNTの値を取り出し、receivedMessageに格納します。receivedMessageは@Publishedに指定しており、あとでSwiftUIで表示します。
最後に送信ボタンが押された時に、Apple WatchにsendMessageするためのsend()メソッドを作ります。
func send() { if WCSession.default.isReachable { count += 1 WCSession.default.sendMessage(["PHONE_COUNT" : count], replyHandler: nil) { error in print(error) } } }
iPhone側からは”PHONE_COUNT”というキーでカウンタを送る仕様にしました。
これでApple Watchと通信するクラスの作成は終わりです。とても簡単ですね。
ContextView
通信する部分ができたので、UIを作ります。
import SwiftUI struct ContentView: View { @ObservedObject var connector = WatchConnector() var body: some View { VStack { HStack { Text("\(connector.count)") Button(action: { self.connector.send() }) { Text("送信") } } Text("\(self.connector.receivedMessage)") } } }
説明は不要ですね。
Apple Watch側のコード
Apple Watch側でも同様に次の2つのクラスを作ります。
- PhoneConnector
- iPhoneと通信するモジュールです。
- ContextView
- デフォルトで作られるViewです。ここでUIを作ります。
PhoneConnector
iPhone側とほとんど同じです。
import UIKit import WatchConnectivity class PhoneConnector: NSObject, ObservableObject, WCSessionDelegate { @Published var receivedMessage = "PHONE : 未受信" @Published var count = 0 override init() { super.init() if WCSession.isSupported() { WCSession.default.delegate = self WCSession.default.activate() } } func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { print("activationDidCompleteWith state= \(activationState.rawValue)") } func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { print("didReceiveMessage: \(message)") DispatchQueue.main.async { self.receivedMessage = "PHONE : \(message["PHONE_COUNT"] as! Int)" } } func send() { if WCSession.default.isReachable { count += 1 WCSession.default.sendMessage(["WATCH_COUNT" : count], replyHandler: nil) { error in print(error) } } } }
違うのは、WCSessionDelegateの下記の2つのメソッドがない点です。Apple Watch側ではこれらのメソッドはサポートされていません。
func sessionDidBecomeInactive(_ session: WCSession) { print("sessionDidBecomeInactive") } func sessionDidDeactivate(_ session: WCSession) { print("sessionDidDeactivate") }
Context View
説明不要なくらい同じです。
struct ContentView: View { @ObservedObject var connector = PhoneConnector() var body: some View { VStack { HStack { Text("\(connector.count)") Button(action: { self.connector.send() }) { Text("送信") } } Text("\(self.connector.receivedMessage)") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
以上でコードの作成は完了です。すべてのコードは GitHubに公開していますので、ご自由に利用してください。
WatchConnectivitySample – GitHub
動作確認
コードの作成が終わったら実機にインストールして動作確認してみましょう。

お互いにカウンタが送受信できていることを確認してください。
終わりに
本記事では、Watch Connectivityの超シンプルなコードを紹介しました。これを動かすことで、Watch Connectivityの基本を抑えられると思います。
今回はsendMessageしか使いませんでしたが、他にも通信方式があります。どういった通信があるかは、下記の記事を参考にしてください。
iPhoneとApple Watch間で通信するための2つの方法【Swift】
他の通信方式のサンプルは公式を見るのが良いでしょう。本記事のコードを理解したあとであれば、そこまで難しくないと思います。
Using Watch Connectivity to Communicate Between Your Apple Watch App and iPhone App
以上です。お疲れ様でした!