Zum Inhalt springen

Erstellen einer watchOS App

GitHub

In diesem Guide lernst du, wie du eine watchOS Companion-App von Grund auf erstellst – inklusive Projekt-Setup in Xcode, Integration des CapgoWatchSDK und dem Erstellen einer funktionalen Watch-App mit SwiftUI.

Für Wear OS nutze Erstellen einer Wear OS-App stattdessen.

Before you begin, ensure you have:

  • Xcode 15 oder neuer (Download im Mac App Store)
  • macOS Sonoma oder neuer (für das neueste watchOS SDK)
  • Ein bestehendes Capacitor iOS-Projekt (ausführen, npx cap add ios falls noch nicht geschehen)
  • Apple Developer Account (kostenloser Account reicht für Entwicklung)

Nach diesem Guide hat dein Projekt diese Struktur:

  • Verzeichnisios/
    • VerzeichnisApp/
      • VerzeichnisApp/ (deine Haupt-iOS-App)
        • …
      • App.xcodeproj
      • App.xcworkspace (nutze dies zum Öffnen des Projekts)
      • Podfile
    • VerzeichnisMyWatch/ (neue Watch-App)
      • VerzeichnisMyWatch/ (Watch-App Quellcode)
        • MyWatchApp.swift
        • ContentView.swift
        • VerzeichnisAssets.xcassets/
          • …
      • MyWatch.xcodeproj
  1. Navigiere zu deinem Capacitor Projekt ios/App Ordner
  2. Öffne App.xcworkspace (nicht .xcodeproj) durch Doppelklick
  3. Warten, bis Xcode das Projekt indiziert
  1. Gehe in Xcode zu Datei → Neu → Ziel…

  2. Wähle im Template-Menü:

    • Wähle watchOS Tab oben aus
    • Wähle App
    • Klicke auf Weiter
  3. Konfiguriere deine Watch-App:

    • Produktname: MyWatch (oder dein bevorzugter Name)
    • Team: Wähle dein Apple Developer Team aus
    • Organization Identifier: Muss mit deiner iOS-App übereinstimmen (z. B. app.capgo)
    • Bundle-Identifier: Wird automatisch generiert (z. B. app.capgo.myapp.watchkitapp)
    • Sprache: Swift
    • Benutzeroberfläche: SwiftUI
    • Watch App Typ: App (nicht für bestehende iOS-Apps)
    • Deaktivieren Notification Scene einschließen (außer du benötigst sie)
    • Deaktivieren Complication einschließen (außer du benötigst sie)
  4. Klicken Fertigstellen

  5. Wenn „‘MyWatch‘-Schema aktivieren?“ erscheint, klicke auf Aktivieren

Schritt 3: Watch-App-Einstellungen konfigurieren

Abschnitt: „Schritt 3: Watch App Einstellungen konfigurieren“
  1. Wähle dein Projekt im Project Navigator (linke Seitenleiste) aus (das blaue Icon oben)

  2. Wähle dein Watch-Target (z. B. „MyWatch“) aus der Targets-Liste aus

  3. Gehe zum Tab General :

    • Anzeigename: Der Name unter dem App-Icon (z. B. „Meine App“)
    • Bundle-Identifier: Muss enden mit .watchkitapp
    • Version: Muss mit deiner iOS-App-Version übereinstimmen
    • Build: Passe deine iOS-Buildnummer an
  4. Gehe zu Signing & Capabilities Tab:

    • Aktivieren Signing automatisch verwalten
    • Wähle dein Team
    • Xcode erstellt Provisioning Profiles automatisch
  5. Setzen Sie Deployment-Infos:

    • Mindestversionen: watchOS 9.0 oder neuer

Schritt 4: CapgoWatchSDK via Swift Package Manager hinzufügen

Abschnitt mit dem Titel „Schritt 4: CapgoWatchSDK via Swift Package Manager hinzufügen“

Das CapgoWatchSDK bietet eine einsatzbereite WatchConnector Klasse für die Kommunikation.

  1. Gehe in Xcode zu Ablage → Paketabhängigkeiten hinzufügen…

  2. Gib im Suchfeld Folgendes ein:

    https://github.com/Cap-go/capacitor-watch.git
  3. Drücke Enter und warte, bis Xcode das Package lädt

  4. Konfiguriere das Package:

    • Dependency-Regel: „Bis zur nächsten Major-Version“ mit „8.0.0“
    • Klicken Package hinzufügen
  5. Wähle aus, welche Produkte hinzugefügt werden sollen:

    • WICHTIG: Wähle nur CapgoWatchSDK
    • Stelle sicher, dass es zu deinem Watch-Ziel festlegen (z. B. „MyWatch“), nicht die iOS-App
    • Klicken Package hinzufügen

Erstellen wir nun die Watch-App code. Ersetze die automatisch generierten Dateien durch folgende:

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

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

Deine iOS-App benötigt zudem die WatchConnectivity-Capability.

  1. Wähle dein Projekt im Project Navigator aus

  2. Wähle dein iOS App Target (nicht das Watch-Target)

  3. Gehe zu Signing & Capabilities Tab

  4. Klicke auf + Capability

  5. Suche nach und füge hinzu: WatchConnectivity (falls verfügbar) oder es wird automatisch hinzugefügt

  6. Das Capacitor Plugin übernimmt die iOS-Seite automatisch, stelle aber sicher, dass deine Info.plist Folgendes enthält:

    <key>WKCompanionAppBundleIdentifier</key>
    <string>app.capgo.myapp.watchkitapp</string>
  1. Wähle dein Watch-Scheme im Scheme-Selector (oben im Xcode-Fenster) aus

  2. Wähle einen Watch-Simulator aus:

    • Klicke auf den Device-Selector neben dem Scheme
    • Wähle einen Apple Watch Simulator (z. B. „Apple Watch Series 9 (45mm)“)
  3. Klicke auf den Ausführen Button (▶️) oder drücke Cmd + R

  4. Der iOS Simulator startet mit iPhone und Apple Watch

Auf einem echten Gerät ausführen

Abschnitt „Auf einem echten Gerät ausführen“
  1. Verbinde dein iPhone per USB

  2. Stelle sicher, dass deine Apple Watch mit diesem iPhone gekoppelt ist

  3. Wähle dein Watch-Scheme aus

  4. Wähle deine physische Apple Watch aus der Geräteliste aus

  5. Klicken Ausführen

  6. Beim ersten Mal: Eventuell musst du deinem Computer auf beiden Geräten vertrauen

In deiner Capacitor-App:

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

Die Watch-App nutzt 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)")
}

Nachrichten auf dem iPhone verarbeiten

Abschnitt: „Nachrichten auf dem iPhone verarbeiten“
// 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'] }
});
});

Wenn du mehr Kontrolle benötigst, implementiere 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()

Watch App wird auf der Watch nicht angezeigt

Abschnitt „Watch-App wird nicht auf der Watch angezeigt“
  1. Stelle sicher, dass die Bundle IDs korrekt verknüpft sind (die Bundle ID der Watch-App muss die iOS-App Bundle ID + .watchkitapp)
  2. Prüfe, ob beide Apps mit demselben Team signiert sind
  3. Auf einem physischen Gerät: Watch App auf dem iPhone öffnen → Meine Watch → scrolle zu deiner App → auf AN stellen

Nachrichten werden nicht empfangen

Abschnitt: „Nachrichten werden nicht empfangen“
  1. Prüfen, ob WCSession in beiden Apps aktiviert ist
  2. Prüfen isReachable vor dem Senden von Nachrichten
  3. Für garantierte Zustellung verwenden Sie transferUserInfo anstatt sendMessage
  4. Sicherstellen, dass Listener registriert sind, bevor das andere Gerät Nachrichten sendet

Fehler „Session Not Activated“

Abschnitt: „Fehler „Session Not Activated““
  1. Rufe WatchConnector.shared.activate() früh im App-Lifecycle
  2. Unter iOS wird das Plugin automatisch aktiviert – stelle sicher, dass das Plugin importiert wurde
  3. Prüfen, ob die WatchConnectivity-Capability zum iOS-Target hinzugefügt wurde
  1. Stelle sicher, dass das Package zum Watch-Targethinzugefügt wurde, nicht zum iOS-Target
  2. Build-Ordner bereinigen: Produkt → Clean Build Folder (Cmd + Shift + K)
  3. Package-Caches zurücksetzen: Datei → Packages → Package Caches zurücksetzen
  1. Setze die Simulatoren zurück: Einstellungen → Alle Inhalte & Einstellungen löschen
  2. Stelle sicher, dass iOS- und watchOS-Simulatoren kompatibel sind
  3. Beide Simulatoren müssen laufen, damit die Kommunikation funktioniert

Wenn du es nutzt Erstellen einer watchOS App Um die Arbeit an nativen Plugins zu planen, verbinde sie mit Verwendung von @capgo/capacitor-watch für die native Funktion in „Verwendung von @capgo/capacitor-watch“, Capgo Plugin-Verzeichnis für den Produkt-Workflow im Capgo Plugin-Verzeichnis, Capacitor Plugins von Capgo für das Implementierungsdetail in Capacitor Plugins von Capgo, Plugins hinzufügen oder aktualisieren für das Implementierungsdetail beim Hinzufügen oder Aktualisieren von Plugins, und Ionic Enterprise Plugin-Alternativen für den Produkt-Workflow bei den Ionic Enterprise Plugin-Alternativen.