跳转到正文

创建 watchOS App

GitHub

本指南将带你从零开始创建一个 watchOS 配套 App,包括在 Xcode 中进行项目设置、集成 CapgoWatchSDK,以及使用 SwiftUI 构建功能完备的 watch App。

对于 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 app)
      • 目录MyWatch/ (watch app 源码)
        • MyWatchApp.swift
        • ContentView.swift
        • 目录Assets.xcassets/
          • …
      • MyWatch.xcodeproj

第 1 步:在 Xcode 中打开 iOS 项目

标题为“第 1 步:在 Xcode 中打开您的 iOS 项目”
  1. 导航至您的 Capacitor 项目 ios/App 文件夹
  2. 打开 App.xcworkspace (不是 .xcodeproj),双击打开
  3. 等待 Xcode 索引项目
  1. 在 Xcode 中,前往 文件 → 新建 → Target…

  2. 在模板选择器中:

    • 选择 watchOS 顶部的标签页
    • 选择 应用
    • 点击 下一页
  3. 配置您的 watch app:

    • 产品名称: MyWatch (或你自定义的名称)
    • 团队:选择你的 Apple Developer 团队
    • 组织标识符:应与你的 iOS App 一致(例如: app.capgo)
    • Bundle 标识符:将自动生成(例如: app.capgo.myapp.watchkitapp)
    • 语言:Swift
    • 用户界面:SwiftUI
    • Watch App 类型: App(而非现有 iOS App 的 App)
    • 取消勾选 包含 Notification Scene (除非你有此需求)
    • 取消勾选 包含 Complication (除非你有此需求)
  4. 点击 完成

  5. 当弹出 “Activate ‘MyWatch’ scheme?” 时,点击 Activate

  1. 在 Project Navigator(左侧边栏)中,选择你的项目(顶部的蓝色图标)

  2. 从 target 列表中选择你的 watch target(例如“MyWatch”)

  3. 前往 常规 标签页:

    • 显示名称:显示在 App 图标下方的名称(例如“My App”)
    • Bundle 标识符:应以……结尾 .watchkitapp
    • 版本:请与你的 iOS App 版本保持一致
    • 构建: 使 iOS App 的 build number 与之匹配
  4. 前往 签名与功能 标签页:

    • 启用 自动管理签名
    • 选择你的 团队
    • Xcode 将自动创建 provisioning profiles
  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 获取该 package

  4. 配置该 package:

    • 依赖版本规则: 使用 “^8.0.0” (Up to Next Major Version)
    • 点击 添加 Package
  5. 选择要添加的产品:

    • 重要提示: 仅选择 CapgoWatchSDK
    • 请确保已将其添加到您的 watch 目标 (例如 “MyWatch”),而非 iOS app
    • 点击 添加 Package

现在来创建 watch app 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 App 还需要 WatchConnectivity 能力。

  1. 在 Project Navigator 中,选择你的项目

  2. 选择你的 iOS App Target (而不是 watch target)

  3. 前往 签名与功能 选项卡

  4. 点击 + 功能

  5. 搜索并添加 WatchConnectivity (如果可用)或可能已自动添加

  6. Capacitor 插件会自动处理 iOS 端,但请确保您的 Info.plist 包含:

    <key>WKCompanionAppBundleIdentifier</key>
    <string>app.capgo.myapp.watchkitapp</string>
  1. 从 Scheme 选择器(Xcode 窗口顶部)中选择你的 Watch Scheme

  2. 选择一个 Apple Watch 模拟器:

    • 点击 Scheme 旁边的设备选择器
    • 选择一个 Apple Watch 模拟器(例如 “Apple Watch Series 9 (45mm)”)
  3. 点击 运行 按钮 (▶️) 或按 Cmd + R

  4. iOS Simulator 将同时启动 iPhone 和 Apple Watch

  1. 通过 USB 连接你的 iPhone

  2. 确保你的 Apple Watch 已与那台 iPhone 配对

  3. 选择你的 watch scheme

  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'] }
});
});

高级:自定义 Delegate 实现更精细的控制

标题为“高级:自定义 Delegate 实现更精细的控制”的章节

如果需要更多控制,请实现 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 App 的 Bundle ID + .watchkitapp)
  2. 检查两个 App 是否由同一个 Team 签名
  3. 在真机上:在 iPhone 上打开 Watch App → 我的手表 → 滚动找到你的 App → 打开开关

无法接收消息

“未收到消息”章节
  1. 验证两个 App 的 WCSession 是否都已激活
  2. 查看 isReachable 发送消息前
  3. 如需保证送达,请使用 transferUserInfo 而不是 sendMessage
  4. 确保在另一台设备发送消息前已注册监听器

“Session Not Activated” 错误

“Session Not Activated” 错误章节
  1. 调用 WatchConnector.shared.activate() 在 App 生命周期早期
  2. 在 iOS 上,插件会自动激活 —— 请确保已导入插件
  3. 检查 iOS target 是否已添加 WatchConnectivity capability
  1. 确保该 package 已添加到 watch 目标而非 iOS target
  2. 清理构建文件夹: 产品 → 清理 Build 文件夹 (Cmd + Shift + K)
  3. 重置 package 缓存: 文件 → Packages → Reset Package Caches
  1. 重置模拟器: 设备 → 抹掉所有内容和设置
  2. 确保 iOS 和 watchOS 模拟器版本匹配
  3. 必须同时运行两个模拟器才能进行通信

如果你正在使用 创建 watchOS App 要规划原生插件工作,请将其与 使用 @capgo/capacitor-watch 用于《使用 @capgo/capacitor-watch》中的原生能力, Capgo 插件目录 查看 Capgo 插件目录中的产品工作流, Capgo 提供的 Capacitor 插件 查看由 Capgo 提供的 Capacitor 插件中的实现细节, 添加或更新插件 关于“添加或更新插件”中的实现细节,以及 Ionic Enterprise 插件替代方案 关于“Ionic Enterprise 插件替代方案”中的产品工作流。