メインコンテンツへスキップ

watchOS アプリの作成

GitHub

このガイドでは、以下の手順に従って watchOS コンパニオンアプリをゼロから作成する方法を説明します。Xcodeでのプロジェクト設定、CapgoWatchSDKの統合、そしてSwiftUIを使用した機能的なwatchアプリの構築までをカバーしています。

以下の Wear OSの場合は、 Wear OSアプリの作成 こちらを読んでください。

開始する前に、以下が準備されていることを確認してください:

  • Xcode 15以降 (Mac App Storeからダウンロード)
  • macOS Sonoma 以降 (最新の watchOS SDK 用)
  • 既存の Capacitor iOS プロジェクト (まだ実行して npx cap add ios いない場合は実行)
  • Apple Developer アカウント (開発には無料アカウントでも可能)

このガイドを完了すると、プロジェクトは以下の構成になります:

  • ディレクトリios/
    • ディレクトリApp/
      • ディレクトリApp/ (メインのiOSアプリ)
        • …
      • App.xcodeproj
      • App.xcworkspace (プロジェクトを開く際に使用)
      • Podfile
    • ディレクトリMyWatch/ (新しいwatchアプリ)
      • ディレクトリMyWatch/ (watchアプリのソース)
        • MyWatchApp.swift
        • ContentView.swift
        • ディレクトリAssets.xcassets/
          • …
      • MyWatch.xcodeproj
  1. Capacitor プロジェクトのディレクトリへ移動します ios/App フォルダ
  2. 開く App.xcworkspace ( .xcodeproj) をダブルクリックして開く
  3. Xcode のプロジェクト・インデックス作成を待機してください
  1. Xcodeで、 File → New → Target… を選択します。

  2. テンプレート選択画面で:

    • 選択します watchOS 上部のタブを選択し、
    • 選択: アプリ
    • クリック 次へ
  3. watchアプリの設定を行います:

    • 製品名: MyWatch (または任意の名前)
    • チーム: Apple Developer チームを選択してください
    • Organization Identifier: iOS アプリと一致させる必要があります (例: app.capgo)
    • Bundle Identifier: 自動生成されます (例: app.capgo.myapp.watchkitapp)
    • 言語: Swift
    • ユーザーインターフェース: SwiftUI
    • Watchアプリのタイプ: App(既存のiOS Appではなく)
    • チェックを外す 通知シーンを含める (必要ない場合)
    • チェックを外す コンプリケーションを追加する (必要ない場合)
  4. クリック 完了

  5. “Activate ‘MyWatch’ scheme?”と表示されたら、クリックします アクティブ化

  1. Project Navigator(左サイドバー)で、プロジェクト(一番上の青いアイコン)を選択します

  2. ターゲット一覧から Watch ターゲット(例: “MyWatch”)を選択します

  3. 以下にアクセスしてください: 一般 タブ:

    • 表示名: アプリアイコンの下に表示される名前(例: “My App”)
    • Bundle Identifier: 末尾は以下で終わる必要があります .watchkitapp
    • バージョン: iOS アプリのバージョンと一致させてください
    • ビルド: iOSアプリのビルド番号を一致させる
  4. 以下に移動します: 署名とCapabilitiesの設定 タブ:

    • 有効にする 署名を自動管理
    • 以下を選択してください: チーム
    • Xcodeがプロビジョニングプロファイルを自動的に作成します
  5. 設定 デプロイ情報:

    • 最小デプロイ要件: watchOS 9.0以降

ステップ 4: Swift Package ManagerでCapgoWatchSDKを追加

「ステップ 4: Swift Package ManagerでCapgoWatchSDKを追加」セクション

CapgoWatchSDKは、すぐに利用可能な WatchConnector 通信用classを提供します。

  1. Xcodeで、以下を選択します: ファイル → Package Dependencies を追加…

  2. 検索フィールドに以下を入力してください:

    https://github.com/Cap-go/capacitor-watch.git
  3. Enterキーを押し、Xcodeがパッケージを取得するまで待ちます

  4. パッケージの設定:

    • 依存関係のルール: 「Up to Next Major Version」を「8.0.0」に設定
    • クリック パッケージの追加
  5. 追加する製品を選択してください:

    • 重要: 以下のみを選択してください CapgoWatchSDK
    • 必ず以下の項目に追加されていることを確認してください: watch ターゲット (例: “MyWatch”) iOSアプリ側ではなく
    • クリック パッケージの追加

次に、watchアプリの code を作成します。自動生成されたファイルを以下の内容に置き換えてください:

編集 MyWatch/MyWatchApp.swift:

import SwiftUI
import CapgoWatchSDK
@main
struct MyWatchApp: App {
init() {
// Activate WatchConnectivity when app launches
WatchConnector.shared.activate()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

編集 MyWatch/ContentView.swift:

import SwiftUI
import CapgoWatchSDK
struct ContentView: View {
// Observe the WatchConnector for automatic UI updates
@ObservedObject var connector = WatchConnector.shared
// Local state
@State private var messageText = ""
@State private var statusMessage = "Ready"
var body: some View {
ScrollView {
VStack(spacing: 16) {
// Connection Status
ConnectionStatusView(connector: connector)
Divider()
// Message Input
TextField("Message", text: $messageText)
.textFieldStyle(.roundedBorder)
// Send Buttons
HStack {
Button("Send") {
sendMessage()
}
.disabled(!connector.isReachable || messageText.isEmpty)
Button("Request") {
sendWithReply()
}
.disabled(!connector.isReachable || messageText.isEmpty)
}
Divider()
// Status
Text(statusMessage)
.font(.caption)
.foregroundColor(.secondary)
// Last Received Message
if !connector.lastMessage.isEmpty {
VStack(alignment: .leading) {
Text("Last Message:")
.font(.caption)
.foregroundColor(.secondary)
Text(formatMessage(connector.lastMessage))
.font(.caption2)
}
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.padding()
}
}
private func sendMessage() {
connector.sendMessage(["text": messageText, "timestamp": Date().timeIntervalSince1970])
statusMessage = "Message sent"
messageText = ""
}
private func sendWithReply() {
connector.sendMessage(["text": messageText, "needsReply": true]) { reply in
DispatchQueue.main.async {
statusMessage = "Reply: \(formatMessage(reply))"
}
}
messageText = ""
}
private func formatMessage(_ message: [String: Any]) -> String {
message.map { "\($0.key): \($0.value)" }.joined(separator: ", ")
}
}
// Separate view for connection status
struct ConnectionStatusView: View {
@ObservedObject var connector: WatchConnector
var body: some View {
HStack {
Circle()
.fill(connector.isReachable ? Color.green : Color.red)
.frame(width: 12, height: 12)
Text(connector.isReachable ? "Connected" : "Disconnected")
.font(.headline)
Spacer()
if connector.isActivated {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
}
}
}
}
#Preview {
ContentView()
}

iOS アプリにも WatchConnectivity の capability が必要です。

  1. Project Navigator でプロジェクトを選択します

  2. 次を選択: iOS App ターゲット (watch ターゲットではありません)

  3. 以下に移動します: Signing & Capabilities タブ

  4. クリック + Capability

  5. 検索して追加 WatchConnectivity (利用可能な場合) または自動的に追加されます

  6. Capacitor プラグインが iOS 側の処理を自動で行いますが、Info.plist に以下が含まれていることを確認してください:

    <key>WKCompanionAppBundleIdentifier</key>
    <string>app.capgo.myapp.watchkitapp</string>

ステップ 7: ビルドと実行

「Step 7: Build and Run」セクション
  1. スキームセレクタ(Xcodeウィンドウ上部)からwatchのスキームを選択します

  2. Apple Watchのシミュレータを選択してください:

    • スキームの隣にあるデバイスセレクタをクリックします
    • Apple Watchのシミュレータを選択します(例:「Apple Watch Series 9 (45mm)」)
  3. 次をクリックします: 実行 ボタン (▶️) をクリックするか、キーを押します Cmd + R

  4. iPhoneとApple Watchの両方が起動した状態でiOS Simulatorが立ち上がります

  1. iPhoneをUSBで接続します

  2. Apple WatchがそのiPhoneとペアリングされていることを確認してください

  3. Watchのスキームを選択してください

  4. デバイスリストから実機のApple Watchを選択してください

  5. クリック 実行

  6. 初回のみ:両方のデバイスでコンピュータを信頼する必要がある場合があります

ステップ 8: 通信テスト

ステップ 8: 通信テスト

iPhone (Capacitor) から Watch へ

iPhone (Capacitor) から Watch へ

Capacitor アプリ内での操作:

import { CapgoWatch } from '@capgo/capacitor-watch';
// Check connection
const info = await CapgoWatch.getInfo();
console.log('Watch reachable:', info.isReachable);
// Send a message
if (info.isReachable) {
await CapgoWatch.sendMessage({
data: { action: 'update', value: 'Hello from iPhone!' }
});
}

Watch から iPhone へ

Watch から iPhone へ

Watch アプリで使用するもの WatchConnector:

// Send message (fire and forget)
WatchConnector.shared.sendMessage(["action": "buttonTapped"])
// Send message with reply
WatchConnector.shared.sendMessage(["request": "getData"]) { reply in
print("Got reply: \(reply)")
}

iPhone でメッセージを処理する

iPhone でメッセージを処理する
// Listen for messages from watch
await CapgoWatch.addListener('messageReceived', (event) => {
console.log('Message from watch:', event.message);
// { action: 'buttonTapped' }
});
// Handle messages that need a reply
await CapgoWatch.addListener('messageReceivedWithReply', async (event) => {
console.log('Request from watch:', event.message);
// Send reply back
await CapgoWatch.replyToMessage({
callbackId: event.callbackId,
data: { status: 'success', items: ['item1', 'item2'] }
});
});

より詳細な制御が必要な場合は、以下を実装してください: WatchConnectorDelegate:

import SwiftUI
import CapgoWatchSDK
class WatchHandler: WatchConnectorDelegate {
func didReceiveMessage(_ message: [String: Any]) {
print("Received: \(message)")
// Handle incoming message
}
func didReceiveMessageWithReply(_ message: [String: Any],
replyHandler: @escaping ([String: Any]) -> Void) {
print("Received request: \(message)")
// Process and send reply
replyHandler(["status": "processed"])
}
func didReceiveApplicationContext(_ context: [String: Any]) {
print("Context updated: \(context)")
}
func didReceiveUserInfo(_ userInfo: [String: Any]) {
print("User info received: \(userInfo)")
}
func reachabilityDidChange(_ isReachable: Bool) {
print("Reachability changed: \(isReachable)")
}
func activationDidComplete(with state: WCSessionActivationState) {
print("Activation completed: \(state.rawValue)")
}
}
// In your app setup:
let handler = WatchHandler()
WatchConnector.shared.delegate = handler
WatchConnector.shared.activate()
  1. Bundle IDが正しく関連付けられていることを確認してください(Watch AppのBundle IDは、iOSアプリのBundle IDに .watchkitapp)
  2. 両方のアプリが同じチームで署名されていることを確認してください
  3. 実機の場合:iPhoneでWatchアプリを開く → My Watch → アプリを探してスクロール → ONに切り替える
  1. 両方のアプリでWCSessionが有効であることを確認してください
  2. 確認 isReachable メッセージを送信する前に
  3. 確実に配信するには、以下を使用してください transferUserInfo の代わりに sendMessage
  4. もう一方のデバイスがメッセージを送信する前に、リスナーが登録されていることを確認してください

“Session Not Activated” エラー

「Session Not Activated」エラーセクション
  1. 呼び出す WatchConnector.shared.activate() アプリのライフサイクル初期に
  2. iOSではプラグインが自動的に有効化されます。プラグインがインポートされていることを確認してください
  3. iOSターゲットにWatchConnectivity capabilityが追加されているか確認してください
  1. パッケージが以下に追加されていることを確認してください: watchターゲット(iOSターゲットではなく)
  2. ビルドフォルダのクリーン: 製品 → Clean Build Folder (Cmd + Shift + K)
  3. パッケージキャッシュのリセット: ファイル → Packages → Reset Package Caches
  1. シミュレータをリセットしてください: 設定 → すべてのコンテンツと設定を消去
  2. iOSとwatchOSのシミュレータが互換性のあるペアであることを確認してください
  3. 通信を機能させるには、両方のシミュレータが起動している必要があります

「watchOS App の作成」の続きを読む

「Creating a watchOS App」からの続き

使用している場合 watchOS アプリの作成 ネイティブプラグインの作業を計画するには、次と連携してください: @capgo/capacitor-watch の使用方法 Using @capgo/capacitor-watch でのネイティブ機能について Capgo プラグインディレクトリ Capgo プラグインディレクトリのプロダクトワークフローについては、 Capgo による Capacitor プラグイン Capgo による Capacitor プラグインの実装詳細については、 プラグインの追加または更新 プラグインの追加または更新における実装詳細については、および Ionic Enterprise プラグインの代替案 Ionic Enterprise プラグインの代替案におけるプロダクトワークフローについては。