macOS 보이스 오버레이 라이프사이클 관리하기
음성 명령 기능을 개발하다 보면 여러 입력 방식이 충돌해서 사용자 경험이 꼬이는 경우가 자주 발생해요. 예를 들어 wake-word로 음성 인식을 시작했는데 중간에 사용자가 단축키(push-to-talk)를 누르면, 기존에 인식되던 텍스트가 사라지거나 오버레이가 제멋대로 닫히는 식이죠. 이런 상태 관리의 복잡함은 개발자를 참 힘들게 만듭니다.
macOS 앱에서 wake-word와 push-to-talk이 겹칠 때 보이스 오버레이를 안정적으로 유지하는 최적의 구현 방법을 정리해 드릴게요.
필요한 것
섹션 제목: “필요한 것”- macOS 앱 컨트리뷰터 권한
빠른 시작
섹션 제목: “빠른 시작”오버레이의 예측 가능성을 높이기 위해 5분 안에 적용할 수 있는 핵심 단계입니다.
-
VoiceSessionCoordinator (actor) 도입 한 번에 딱 하나의
VoiceSession만 관리하도록 설계하세요. 토큰 기반 API(beginWakeCapture,beginPushToTalk,endCapture등)를 사용해 오래된 콜백이 오버레이를 다시 여는 현상을 방지합니다. -
세션 채택(Adoption) 로직 적용 wake-word로 오버레이가 이미 떠 있는 상태에서 사용자가 단축키를 누르면, 세션을 초기화하는 대신 기존 텍스트를 그대로 가져옵니다. 단축키를 떼기 전까지 오버레이를 유지하고, 텍스트가 있으면 전송하고 없으면 닫습니다.
-
VoiceSessionPublisher로 SwiftUI 연결
ObservableObject인VoiceSessionPublisher가 활성 세션의 상태를 SwiftUI 뷰(VoiceWakeOverlayView)에 전달하게 하세요. 뷰가 직접 싱글톤을 수정하지 않고 퍼블리셔를 통해서만 렌더링되도록 구성합니다. -
통합된 전송 경로(Unified send path) 사용
endCapture시점에 텍스트가 비어 있으면 즉시 dismiss하고, 텍스트가 있다면performSend를 호출합니다. push-to-talk 종료 후에는 짧은 cooldown을 적용해 wake-word가 즉시 재트리거되지 않도록 관리하세요.
문제 해결
섹션 제목: “문제 해결”오버레이가 화면에서 사라지지 않거나 동작이 이상할 때는 다음 명령어로 로그를 확인해 보세요.
sudo log stream --predicate 'subsystem == "bot.molt" AND category CONTAINS "voicewake"' --level info --style compact체크리스트:
- 활성 세션 토큰이 하나만 유지되는지 확인하세요. 오래된 콜백은 coordinator에서 드랍되어야 합니다.
- push-to-talk을 뗐을 때 항상 활성 토큰과 함께
endCapture가 호출되는지 확인하세요. 텍스트가 없다면 전송음 없이dismiss되어야 정상입니다.
도움이 더 필요하신가요? AI Setup Assistant에서 바로 물어보세요.
다음 단계
섹션 제목: “다음 단계”VoiceSession모델 상세 구조 보기VoiceWakeRuntime리팩토링 가이드VoicePushToTalk세션 채택 로직 구현- 오버레이 바인딩 및 테스트 케이스 추가
OpenClaw Expert
아직 막혀 있나요?
이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.