watchOS 앱 만들기
설치
이 안내서에서는 Xcode에서 프로젝트를 설정하고 CapgoWatchSDK를 통합하여 스위프트 UI로 기능적인 watch 앱을 만드는 과정을 안내합니다.
필수 조건
필수 조건 섹션시작하기 전에 다음을 확인하세요:
- Xcode 15 이상 (Mac 앱 스토어에서 다운로드)
- macOS Sonoma 이상 (최신 watchOS SDK)
- 기존 Capacitor iOS 프로젝트 (실행하시려면
npx cap add ios(만약 아직 실행하지 않았다면) - 애플 개발자 계정 (개발용으로는 무료 계정도 사용 가능)
프로젝트 구조 개요
제목 ‘프로젝트 구조 개요’이 가이드를 완료한 후 프로젝트는 다음과 같은 구조를 가집니다:
폴더ios/
폴더App/
폴더App/ (당신의 메인 iOS 앱)
- …
- App.xcodeproj
- App.xcworkspace 프로젝트를 열기 위해 사용하세요.
- Podfile
디렉토리MyWatch/ 새로운 시계 앱
디렉토리MyWatch/ 시계 앱 소스
- MyWatchApp.swift
- ContentView.swift
폴더Assets.xcassets/
- …
- MyWatch.xcodeproj
Step 1: iOS 프로젝트를 Xcode에서 열어보세요
Step 1: iOS 프로젝트를 Xcode에서 열어보세요- Navigate to your Capacitor project’s
ios/App폴더 - 열기
App.xcworkspace(not.xcodeprojXcode에서 프로젝트를 인덱싱하는 데 몇 초가 걸립니다 - 주의
2단계: watchOS Target 추가
2단계: watchOS Target 추가-
Xcode 에서 파일 → 새로 만들기 → 대상...
-
템플릿 선택기에서:
- 탭을 선택하세요. 탭 탭
- 선택 앱
- 클릭 다음
-
시계 앱을 설정하세요:
- 제품 이름:
MyWatch(또는 선호하는 이름) - 팀: Apple 개발자 팀을 선택하세요
- 회사 식별자: iOS 앱과 일치해야 합니다 (예:
app.capgo) - 식별자: 자동으로 생성됩니다 (예를 들어,
app.capgo.myapp.watchkitapp) - 언어: 스위프트
- 사용자 인터페이스: 스위프트 유이
- WATCH 앱 유형: 기존 iOS 앱이 아닌 앱
- 선택 취소 알림 장면 포함 (만약 필요하다면)
- 선택 취소 복잡성 포함 Live Update
- 제품 이름:
-
Click Finish
-
When prompted “MyWatch” 스키마 활성화 하시겠습니까?”, 클릭 Activate
3. 시계 앱 설정 구성
3. 시계 앱 설정 구성-
프로젝트 탐색기(왼쪽 사이드바)에서 프로젝트를 선택하세요 (상단 blue 아이콘)
-
시계 대상(MyWatch)을 선택하세요
-
설정 설정 General
- 애플리케이션 이름: 앱 아이콘 아래에 표시되는 이름 (예: "My App")
- 아이디:
.watchkitapp - 아이디는버전
- Build빌드
-
: iOS 앱 빌드 번호와 일치 로 이동
- 인증 및 기능 자동으로 서명 관리
- 선택하세요 팀
- Xcode는 자동으로 배포 프로파일을 생성합니다
-
설정 배포 정보:
- 최소 배포: watchOS 9.0 이상
4단계: CapgoWatchSDK를 Swift Package Manager를 통해 추가하세요
4단계: CapgoWatchSDK를 Swift Package Manager를 통해 추가하세요CapgoWatchSDK는 통신을 위한 WatchConnector 클래스를 제공합니다
-
Xcode에서 가서 파일 → 패키지 의존성 추가...
-
검색란에 입력하세요
https://github.com/Cap-go/capacitor-watch.git -
Enter를 누르고 Xcode가 패키지를 가져올 때까지 기다려 주세요.
-
설정 패키지를 구성하십시오.
- 의존성 규칙: “8.0.0까지의 주요 버전”에 “Up to Next Major Version”
- 클릭 패키지 추가
-
추가할 제품을 선택하세요:
- 중요: 오직 선택
CapgoWatchSDK - 정확히 선택하세요 Make sure it’s added to your 시계 목표에 추가되어야 합니다
- watch target 패키지 추가
- 중요: 오직 선택
패키지 추가하기
Step 5: Watch 앱 구현Now let’s create the watch app code. Replace the auto-generated files with the following:
5.1 Watch 앱 진입점 만들기
Section titled “5.1 Watch 앱 진입점 만들기”수정 MyWatch/MyWatchApp.swift:
import SwiftUIimport CapgoWatchSDK
@mainstruct MyWatchApp: App { init() { // Activate WatchConnectivity when app launches WatchConnector.shared.activate() }
var body: some Scene { WindowGroup { ContentView() } }}5.2 메인 뷰 만들기
Section titled “5.2 메인 뷰 만들기”수정 MyWatch/ContentView.swift:
import SwiftUIimport 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 statusstruct 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()}Step 6: WatchConnectivity를 위한 iOS 앱 구성
Section titled “Step 6: WatchConnectivity를 위한 iOS 앱 구성”iOS 앱도 WatchConnectivity 기능이 필요합니다.
-
프로젝트 탐색기에서 프로젝트를 선택하세요.
-
프로젝트 iOS 앱 대상 시계 대상이 아닌
-
다음으로 인증 및 기능 탭
-
클릭 + 기능
-
WatchConnectivity 기능을 검색하고 추가하세요. WatchConnectivity (만약 있다면) 또는 자동으로 추가될 수 있습니다.
-
iOS Capacitor 플러그인은 자동으로 처리하지만 Info.plist에 다음 항목이 포함되어 있어야 합니다.
<key>WKCompanionAppBundleIdentifier</key><string>app.capgo.myapp.watchkitapp</string>
7단계: 빌드 및 실행
7단계: 빌드 및 실행시뮬레이터에서 실행
시뮬레이터에서 실행-
Apple Watch 프로젝트에서 스케마를 선택하세요.
-
Apple Watch 시뮬레이터를 선택하세요.
- 디바이스 선택기에서 클릭하세요.
- Apple Watch 시뮬레이터 (예: "Apple Watch Series 9 (45mm)")를 선택하세요.
-
클릭 실행 버튼 (▶️) 또는 클릭
Cmd + R -
iOS 시뮬레이터는 iPhone과 Apple Watch 모두가 실행됩니다.
실제 기기에서 실행
제목: 실제 기기에서 실행-
iPhone을 USB로 연결하세요
-
Apple Watch가 iPhone과 pair되어 있는지 확인하세요
-
시계 스키마를 선택하세요
-
실제 Apple Watch를 기기 목록에서 선택하세요
-
클릭 실행
-
첫 번째 실행: 두 기기 모두에서 컴퓨터에 신뢰를 주셔야 합니다.
Step 8: 통신 테스트
페이지 제목: Step 8: 통신 테스트iPhone (Capacitor)에서 Watch로
페이지 제목: iPhone (Capacitor)에서 Watch로Capacitor 앱에서:
import { CapgoWatch } from '@capgo/capacitor-watch';
// Check connectionconst info = await CapgoWatch.getInfo();console.log('Watch reachable:', info.isReachable);
// Send a messageif (info.isReachable) { await CapgoWatch.sendMessage({ data: { action: 'update', value: 'Hello from iPhone!' } });}Watch에서 iPhone으로
Section titled “Watch에서 iPhone으로”The watch app uses __CAPGO_KEEP_0__ to display the watch app's UI. WatchConnector:
// Send message (fire and forget)WatchConnector.shared.sendMessage(["action": "buttonTapped"])
// Send message with replyWatchConnector.shared.sendMessage(["request": "getData"]) { reply in print("Got reply: \(reply)")}iPhone에서 메시지 처리
Section titled “iPhone에서 메시지 처리”// Listen for messages from watchawait CapgoWatch.addListener('messageReceived', (event) => { console.log('Message from watch:', event.message); // { action: 'buttonTapped' }});
// Handle messages that need a replyawait 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'] } });});고급: 사용자 지정 위임자로 더 많은 제어
Section titled “고급: 사용자 지정 위임자로 더 많은 제어”더 많은 제어가 필요하면 implement WatchConnectorDelegate:
import SwiftUIimport 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 = handlerWatchConnector.shared.activate()시계 앱이 시계에 나타나지 않습니다.
시계 앱이 시계에 나타나지 않는 이유- 시계 앱과 iOS 앱의 번들 ID가 올바르게 연결되어 있는지 확인하세요. (시계 앱의 번들 ID는 iOS 앱의 번들 ID +)
.watchkitapp) - iOS 앱과 시계 앱이 동일한 팀으로 서명되어 있는지 확인하세요.
- 물리 장치에서: iPhone에서 시계 앱을 열고 → My Watch → 앱을 찾고 → toggle ON
메시지가 전달되지 않습니다.
메시지가 전달되지 않는 이유- WCSession이 활성화되어 있는지 두 앱 모두 확인하세요.
- 확인
isReachable메시지를 전송하기 전에 - 보장된 전달을 위해
transferUserInfo대신sendMessage - 다른 기기에서 메시지를 보내기 전에 리스너가 등록되어 있는지 확인하세요.
세션 활성화 오류
Session Not Activated- Call
WatchConnector.shared.activate()앱 라이프 사이클의 초기 단계에 호출하세요. - iOS에서 플러그인은 자동으로 활성화되므로 플러그인을 임포트하세요.
- iOS 대상에 WatchConnectivity 기능이 추가되어 있는지 확인하세요.
CapgoWatchSDK와 관련된 빌드 오류
CapgoWatchSDK와 관련된 빌드 오류- 패키지가 iOS 대상에 추가되어 있는지 확인하세요. 시계 대상, iOS 대상이 아닌
- 빌드 폴더를 깨끗하게 유지하세요: 제품 → 빌드 폴더를 깨끗하게 유지하세요 (Cmd + Shift + K)
- 패키지 캐시를 초기화하세요: 파일 → 패키지 → 패키지 캐시 초기화
시뮬레이터 문제
시뮬레이터 문제 섹션- 시뮬레이터를 초기화하세요: 디바이스 → 모든 콘텐츠와 설정을 초기화
- iOS와 watchOS 시뮬레이터가 호환되는 pair인지 확인하세요
- 시뮬레이터가 통신을 위해 동작하려면 두 시뮬레이터 모두 동작해야 합니다
다음 단계
다음 단계Creating a watchOS App에서 계속
Creating a watchOS App에서 계속Creating a watchOS App을 사용하여 자연 플러그인 작업을 계획하고 이를 Native Plugin과 연결하세요 native 기능을 위한 @capgo/capacitor-watch 사용 native 기능을 위한 @capgo/capacitor-watch 사용 Capgo 플러그인 디렉토리 Capgo 플러그인 디렉토리 Capacitor 플러그인들에 대한 Capgo Capacitor 플러그인들에 대한 Capgo 플러그인 추가 또는 업데이트 플러그인 추가 또는 업데이트 Ionic Enterprise 플러그인 대체 Ionic Enterprise 플러그인 대체