Shipping Global Keyboard Shortcuts on macOS Sandbox: The Part Apple Doesn't Document
개요
macOS App Sandbox 환경에서 전역 키보드 단축키를 통해 텍스트를 입력하는 기능 구현 시 CGEvent.post()가 차단되는 문제를 해결하기 위해 AppleScript System Events를 활용하는 방법에 대해 설명한다.
주요 내용
- App Sandbox의 CGEvent.post() 차단: Mac App Store 배포를 위해 App Sandbox를 활성화하면
CGEvent.post()를 통한 키보드 입력 시뮬레이션이 에러 없이 조용히 실패한다. 이는 App Sandbox Design Guide에 "Sending synthetic events to other processes is disallowed."라는 한 문장으로만 언급되어 있다. - 전역 키보드 단축키 캡처:
CGEvent.tapCreate를 사용하여.cgSessionEventTap옵션으로 전역 키보드 이벤트(예:keyDown)를 감지할 수 있으며, 이는 App Sandbox 환경에서도 사용자의 "Input Monitoring" 권한 허용 시 정상 작동한다. - 실효성 있는 텍스트 출력 방법: AppleScript System Events: App Sandbox에서
CGEvent.post()대신, 텍스트를 클립보드에 복사한 후 AppleScript를 사용하여 System Events에게 키보드 입력을 요청하는 방식이 작동한다. 이를 위해com.apple.security.automation.apple-events권한이 필요하며, 사용자에게 "QUICOPY wants permission to control System Events."와 같은 허용 프롬프트를 표시해야 한다. - 클립보드 복원 문제: 텍스트 입력을 위해 클립보드 내용을 변경한 후에는 원래 클립보드 내용을 복원해야 한다. 단순한 문자열 복원이 아닌, 이미지, 파일 참조, 리치 텍스트 등 모든 데이터 타입을 보존하기 위해
NSPasteboardItem의 모든 타입을 순회하며 raw Data를 복사하는 방식이 권장된다. - 타이밍 문제 및 지연 시간: AppleScript System Events를 통한 입력 시뮬레이션은
CGEvent.post()보다 약 40-80ms의 지연 시간을 가지며, 클립보드 복원 시에도 100-150ms의 지연이 필요하다. 이는 일반적인 텍스트 확장 사용 사례에서는 인지하기 어려운 수준이나, 실시간 입력이 중요한 애플리케이션에는 부적합할 수 있다. - App Store 리뷰 시 유의점: App Sandbox 환경에서 필요한 권한을 최소화하는 것이 중요하다.
com.apple.security.automation.apple-events권한으로 기능 구현이 가능하다면, 더 높은 권한인 Accessibility API 사용은 피해야 한다. - 최종 아키텍처:
CGEvent Tap으로 단축키 캡처 → 텍스트 스니펫을 클립보드에 로드 →NSAppleScript로 System Events 호출 → System Events가 포커스된 앱에 입력 → 클립보드 복원 (100ms 지연)으로 구성된다.
시사점
Mac App Store에 배포되는 macOS 앱에서 전역 키보드 단축키를 통한 텍스트 입력 기능을 구현할 때 App Sandbox의 제약을 우회하기 위한 AppleScript System Events 활용은 효과적인 대안이며, 클립보드 관리와 권한 최소화가 중요하다.
원문을 불러오는 중...
댓글
GitHub Discussions