本記事では、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
以上です。お疲れ様でした!