Saltar al contenido

Crear una app para watchOS

GitHub

Esta guía te enseñará a crear una watchOS app complementaria desde cero, incluyendo la configuración en Xcode, la integración de CapgoWatchSDK y la creación de una app funcional con SwiftUI.

Para Wear OS, usa Crear una app para Wear OS en su lugar.

Antes de empezar, asegúrate de tener:

  • Xcode 15 o superior (descárgalo de la Mac App Store)
  • macOS Sonoma o posterior (para la última versión de watchOS SDK)
  • Un proyecto iOS existente de Capacitor (ejecuta npx cap add ios si aún no lo has hecho)
  • Cuenta de Apple Developer (la cuenta gratuita sirve para desarrollo)

Tras completar esta guía, tu proyecto tendrá esta estructura:

  • Directorioios/
    • DirectorioApp/
      • DirectorioApp/ (tu app principal de iOS)
        • …
      • App.xcodeproj
      • App.xcworkspace (úsalo para abrir el proyecto)
      • Podfile
    • DirectorioMyWatch/ (nueva app de watch)
      • DirectorioMyWatch/ (código fuente de la app de watch)
        • MyWatchApp.swift
        • ContentView.swift
        • DirectorioAssets.xcassets/
          • …
      • MyWatch.xcodeproj
  1. Navega hasta tu proyecto Capacitor ios/App carpeta
  2. Abrir App.xcworkspace (no .xcodeproj) haciendo doble clic
  3. Espera a que Xcode indexe el proyecto
  1. En Xcode, ve a Archivo → Nuevo → Destino…

  2. En el selector de plantillas:

    • Selecciona watchOS pestaña superior
    • Elige app
    • Haz clic Siguiente
  3. Configura tu app para watchOS:

    • Nombre del producto: MyWatch (o el nombre que prefieras)
    • Equipo: Selecciona tu equipo de Apple Developer
    • Identificador de la organización: Debe coincidir con tu app de iOS (ej., app.capgo)
    • Identificador del bundle: Se generará automáticamente (ej., app.capgo.myapp.watchkitapp)
    • Idioma: Swift
    • Interfaz de usuario: SwiftUI
    • Tipo de aplicación Watch: App (no App para una iOS App existente)
    • Desmarcar Incluir la escena de notificación (a menos que lo necesites)
    • Desmarcar Incluir complicación (a menos que lo necesites)
  4. Haz clic Finalizar

  5. Cuando aparezca “Activate ‘MyWatch’ scheme?”, haz clic en Activar

  1. En el Project Navigator (barra lateral izquierda), selecciona tu proyecto (el icono azul de arriba)

  2. Selecciona tu target de watch (ej. “MyWatch”) de la lista de targets

  3. Ve a la pestaña General pestaña:

    • Nombre visible: El nombre que aparece debajo del icono de la app (ej. “My App”)
    • Identificador del bundle: Debe terminar con .watchkitapp
    • Versión: Coincide con la versión de tu app de iOS
    • Build: Coincide con el número de build de tu app iOS
  4. Ve a Firma y capacidades pestaña:

    • Activar Gestionar la firma automáticamente
    • Selecciona tu Equipo
    • Xcode creará los perfiles de aprovisionamiento automáticamente
  5. Configurar Información de despliegue:

    • Versiones mínimas: watchOS 9.0 o posterior

Paso 4: Añadir CapgoWatchSDK vía Swift Package Manager

Sección titulada “Paso 4: Añadir CapgoWatchSDK vía Swift Package Manager”

El CapgoWatchSDK proporciona una WatchConnector clase para la comunicación.

  1. En Xcode, ve a Archivo → Añadir dependencias de paquetes…

  2. En el campo de búsqueda, escribe:

    https://github.com/Cap-go/capacitor-watch.git
  3. Pulsa Enter y espera a que Xcode descargue el paquete

  4. Configura el paquete:

    • Regla de dependencia: “Up to Next Major Version” con “8.0.0”
    • Haz clic Añadir paquete
  5. Elige qué productos añadir:

    • IMPORTANTE: Solo selecciona CapgoWatchSDK
    • Asegúrate de que se haya añadido a tu target de watch (ej., “MyWatch”), no a la app de iOS
    • Haz clic Añadir paquete

Ahora vamos a crear la watch app code. Reemplaza los archivos autogenerados por los siguientes:

Editar 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()
}
}
}

Editar 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()
}

Paso 6: Configurar la app de iOS para WatchConnectivity

Sección titulada “Paso 6: Configurar la app de iOS para WatchConnectivity”

Tu app de iOS también necesita la capacidad WatchConnectivity.

  1. En el Project Navigator, selecciona tu proyecto

  2. Selecciona tu target de la app iOS (no el target del watch)

  3. Ve a Firma y capacidades pestaña

  4. Haz clic + Capability

  5. Busca y añade WatchConnectivity (si está disponible) o se añadirá automáticamente

  6. El plugin Capacitor gestiona la parte de iOS automáticamente, pero asegúrate de que tu Info.plist tenga:

    <key>WKCompanionAppBundleIdentifier</key>
    <string>app.capgo.myapp.watchkitapp</string>
  1. Selecciona el scheme de tu watch en el selector de schemes (parte superior de Xcode)

  2. Elige un simulador de Apple Watch:

    • Haz clic en el selector de dispositivos junto al scheme
    • Selecciona un simulador de Apple Watch (ej. “Apple Watch Series 9 (45mm)”)
  3. Haz clic en Ejecuta botón (▶️) o presiona Cmd + R

  4. El iOS Simulator se iniciará con el iPhone y el Apple Watch

Ejecutar en dispositivo físico

Sección titulada “Run on Physical Device”
  1. Conecta tu iPhone mediante USB

  2. Asegúrate de que tu Apple Watch esté emparejado con ese iPhone

  3. Selecciona el scheme de tu Apple Watch

  4. Selecciona tu Apple Watch físico en la lista de dispositivos

  5. Haz clic Ejecuta

  6. Primera vez: Es posible que debas confiar en tu ordenador en ambos dispositivos

En tu app de 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!' }
});
}

La app del Watch usa 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)")
}
// 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'] }
});
});

Avanzado: delegate personalizado para más control

Sección titulada “Avanzado: delegate personalizado para más control”

Si necesitas más control, implementa 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. Asegúrate de que los bundle IDs estén correctamente relacionados (el bundle ID de la app Watch debe ser el bundle ID de la app iOS + .watchkitapp)
  2. Verifica que ambas apps estén firmadas con el mismo equipo
  3. En un dispositivo físico: abre la app Watch en el iPhone → Mi Watch → desplázate hasta encontrar tu app → actívala
  1. Verifica que ambas apps tengan WCSession activada
  2. Verificar isReachable antes de enviar mensajes
  3. Para garantizar la entrega, usa transferUserInfo en lugar de sendMessage
  4. Asegúrate de registrar los listeners antes de que el otro dispositivo envíe mensajes
  1. Llama a WatchConnector.shared.activate() al inicio del ciclo de vida de la app
  2. En iOS, el plugin se activa automáticamente; asegúrate de haberlo importado
  3. Verifica que la capacidad WatchConnectivity esté añadida al target de iOS

Errores de build con CapgoWatchSDK

Sección: “Errores de build con CapgoWatchSDK”
  1. Asegúrate de que el paquete esté añadido al target de watch, no al target de iOS
  2. Limpia la carpeta de build: Producto → Limpiar carpeta de build (Cmd + Shift + K)
  3. Reinicia la caché de paquetes: Archivo → Packages → Reset Package Caches
  1. Reinicia los simuladores: Ajustes → Borrar contenidos y ajustes
  2. Asegúrate de que los simuladores de iOS y watchOS sean compatibles
  3. Ambos simuladores deben estar ejecutándose para que la comunicación funcione

Continuar desde Crear una app para watchOS

Sección titulada “Continuar desde Creating a watchOS App”

Si estás usando Crear una app para watchOS para planificar el trabajo con plugins nativos, conéctalo con Usando @capgo/capacitor-watch para la capacidad nativa en Uso de @capgo/capacitor-watch, Directorio de plugins de Capgo para el flujo de trabajo del producto en Capgo Plugin Directory, Plugins de Capacitor por Capgo para el detalle de implementación en los Plugins de Capacitor por Capgo, Añadir o actualizar plugins para el detalle de implementación en Agregar o actualizar plugins, y Alternativas a plugins de Ionic Enterprise para el flujo de trabajo del producto en Alternativas a plugins de Ionic Enterprise.