Vai al contenuto

Creazione di un'app watchOS

GitHub

Questa guida ti mostra come creare una watchOS companion app da zero, incluso il setup del progetto in Xcode, l'integrazione di CapgoWatchSDK e la creazione di un'app watch funzionante con SwiftUI.

Per Wear OS, usa Creazione di un'app Wear OS invece.

Prima di iniziare, assicurati di avere:

  • Xcode 15 o versioni successive (scarica dal Mac App Store)
  • macOS Sonoma o versioni successive (per l'ultima versione di watchOS SDK)
  • Un progetto iOS Capacitor esistente (esegui npx cap add ios se non l'hai fatto)
  • Account Apple Developer (l'account gratuito va bene per lo sviluppo)

Dopo aver completato questa guida, il tuo progetto avrà questa struttura:

  • Directoryios/
    • DirectoryApp/
      • DirectoryApp/ (la tua app iOS principale)
        • …
      • App.xcodeproj
      • App.xcworkspace (usa questo per aprire il progetto)
      • Podfile
    • DirectoryMyWatch/ (nuova watch app)
      • DirectoryMyWatch/ (codice sorgente watch app)
        • MyWatchApp.swift
        • ContentView.swift
        • DirectoryAssets.xcassets/
          • …
      • MyWatch.xcodeproj
  1. Vai alla cartella del tuo progetto Capacitor ios/App cartella
  2. Apri App.xcworkspace (non .xcodeproj) facendoci doppio clic
  3. Attendi che Xcode indicizzi il progetto
  1. In Xcode, vai su File → Nuovo → Target…

  2. Nel selettore dei template:

    • Seleziona watchOS scheda in alto
    • Usa App
    • Clicca su Avanti
  3. Configura la tua watch app:

    • Nome prodotto: MyWatch (o il nome che preferisci)
    • Team: Seleziona il tuo team Apple Developer
    • Identificativo organizzazione: Deve corrispondere alla tua app iOS (es. app.capgo)
    • Bundle Identifier: Sarà generato automaticamente (es. app.capgo.myapp.watchkitapp)
    • Lingua: Swift
    • Interfaccia utente: SwiftUI
    • Tipo di Watch App: App (non App per un'app iOS esistente)
    • Deseleziona Includi Notification Scene (a meno che non ti serva)
    • Deseleziona Includi Complication (a meno che non ti serva)
  4. Clicca su Fine

  5. Quando appare il prompt “Activate ‘MyWatch’ scheme?”, clicca Attiva

Passaggio 3: Configura le impostazioni della Watch App

Sezione intitolata “Passaggio 3: Configura le impostazioni dell'app Watch”
  1. Nel Project Navigator (barra laterale sinistra), seleziona il tuo progetto (l'icona blu in alto)

  2. Seleziona il target watch (es. “MyWatch”) dall'elenco dei target

  3. Vai a Generali scheda:

    • Nome visualizzato: Il nome visualizzato sotto l'icona dell'app (es. “My App”)
    • Bundle Identifier: Deve terminare con .watchkitapp
    • Versione: Deve corrispondere alla versione della tua app iOS
    • Build: Allinea il build number della tua app iOS
  4. Vai su Firma e Capabilities scheda:

    • Abilita Gestisci automaticamente la firma
    • Seleziona la tua Team
    • Xcode creerà i provisioning profile automaticamente
  5. Imposta Info di Deployment:

    • Deployment minimi: watchOS 9.0 o versioni successive

Passaggio 4: Aggiungi CapgoWatchSDK tramite Swift Package Manager

Sezione intitolata “Passaggio 4: Aggiungi CapgoWatchSDK tramite Swift Package Manager”

Il CapgoWatchSDK fornisce una WatchConnector classe pronta all'uso per la comunicazione.

  1. In Xcode, vai su File → Aggiungi dipendenze pacchetto…

  2. Nel campo di ricerca, inserisci:

    https://github.com/Cap-go/capacitor-watch.git
  3. Premi Invio e attendi che Xcode scarichi il package

  4. Configura il package:

    • Regola delle dipendenze: “Fino alla prossima versione major” con “8.0.0”
    • Clicca su Aggiungi pacchetto
  5. Scegli quali prodotti aggiungere:

    • IMPORTANTE: Seleziona solo CapgoWatchSDK
    • Assicurati che sia aggiunto al tuo target watch (es. “MyWatch”), non all'app iOS
    • Clicca su Aggiungi pacchetto

Ora creiamo l'app watch code. Sostituisci i file generati automaticamente con i seguenti:

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

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

Passaggio 6: Configura l'app iOS per WatchConnectivity

Sezione intitolata “Passaggio 6: Configura l'app iOS per WatchConnectivity”

Anche la tua app iOS necessita della capability WatchConnectivity.

  1. Nel Project Navigator, seleziona il tuo progetto

  2. Seleziona la tua Target dell'app iOS (non il target dell'watch)

  3. Vai su Firma e Capabilities scheda

  4. Clicca su + Funzionalità

  5. Cerca e aggiungi WatchConnectivity (se disponibile) o potrebbe essere aggiunto automaticamente

  6. Il plugin Capacitor gestisce automaticamente la parte iOS, ma assicurati che il tuo Info.plist contenga:

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

Esegui sul Simulatore

Sezione: “Run on Simulator”
  1. Seleziona lo scheme per l'watch dal selettore degli schemi (in alto nella finestra di Xcode)

  2. Scegli un simulatore Apple Watch:

    • Clicca sul selettore del dispositivo accanto allo scheme
    • Seleziona un simulatore Apple Watch (es. “Apple Watch Series 9 (45mm)”)
  3. Clicca sul Esegui il tasto (▶️) o premi Cmd + R

  4. L'iOS Simulator si avvierà con iPhone e Apple Watch

Esegui su dispositivo fisico

Sezione: “Run on Physical Device”
  1. Connetti il tuo iPhone via USB

  2. Assicurati che l'Apple Watch sia associato a quell'iPhone

  3. Seleziona lo scheme dell'app watch

  4. Seleziona il tuo Apple Watch fisico dalla lista dei dispositivi

  5. Clicca su Esegui

  6. Prima volta: potresti dover autorizzare il computer su entrambi i dispositivi

Nella tua app 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!' }
});
}

L'app per watch utilizza 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'] }
});
});

Avanzato: Delegate personalizzato per un controllo maggiore

Sezione intitolata “Avanzato: Delegate personalizzato per un controllo maggiore”

Se hai bisogno di maggiore controllo, 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. Assicurati che i bundle ID siano correlati correttamente (il bundle ID dell'app Watch deve essere il bundle ID dell'app iOS + .watchkitapp)
  2. Verifica che entrambe le app siano firmate con lo stesso team
  3. Su dispositivo fisico: Apri l'app Watch su iPhone → Mio Watch → scorri per trovare la tua app → attiva l'interruttore

I messaggi non vengono ricevuti

Sezione: “Messaggi non ricevuti”
  1. Verifica che entrambe le app abbiano WCSession attivata
  2. Verifica isReachable prima di inviare i messaggi
  3. Per una consegna garantita, usa transferUserInfo invece di sendMessage
  4. Assicurati che i listener siano registrati prima che l'altro dispositivo invii messaggi

Errore “Session Not Activated”

Sezione: “Errore: Session Not Activated”
  1. Chiama WatchConnector.shared.activate() nelle fasi iniziali del ciclo di vita dell'app
  2. Su iOS, il plugin si attiva automaticamente: assicurati che sia importato
  3. Verifica che la capability WatchConnectivity sia stata aggiunta al target iOS

Errori di build con CapgoWatchSDK

Sezione: “Errori di build con CapgoWatchSDK”
  1. Assicurati che il pacchetto sia stato aggiunto al target watch, non al target iOS
  2. Pulisci la cartella di build: Prodotto → Pulisci cartella build (Cmd + Shift + K)
  3. Reset della cache dei pacchetti: File → Packages → Reset Package Caches
  1. Resetta i simulatori: Impostazioni → Inizializza contenuto e impostazioni
  2. Assicurati che i simulatori iOS e watchOS siano versioni compatibili
  3. Entrambi i simulatori devono essere attivi per consentire la comunicazione

Se stai usando Creazione di un'app watchOS per pianificare il lavoro sui plugin nativi, collegalo a Utilizzo di @capgo/capacitor-watch per la funzionalità nativa in Utilizzo di @capgo/capacitor-watch, Directory dei plugin di Capgo per il workflow del prodotto nella Capgo Plugin Directory, Plugin Capacitor di Capgo per i dettagli di implementazione in Capacitor Plugins di Capgo, Aggiunta o aggiornamento dei plugin per i dettagli su come aggiungere o aggiornare i plugin, e Alternative ai plugin Ionic Enterprise per il workflow del prodotto in Alternative ai plugin Ionic Enterprise.