Table of Contents
다른 앱이나 시스템에 키 입력을 전달
macOS 앱 개발에서 다른 앱이나 시스템에 키 입력을 전달하려면 Quartz Event Services를 사용하여 가상 키 이벤트를 생성해야 합니다. 특히 Control + 1과 같은 조합 키는 플래그(Flags)를 함께 설정하는 과정이 필요합니다.
구현을 위한 주요 단계는 다음과 같습니다.
1. 샌드박스 및 권한 설정
다른 앱에 키 이벤트를 보내려면 앱 샌드박스(App Sandbox)를 해제하거나, 사용자로부터 손쉬운 사용(Accessibility) 권한을 승인받아야 합니다.
- Xcode 설정:
Signing & Capabilities에서App Sandbox를 제거하거나,Hardened Runtime에서Apple Events를 허용해야 할 수 있습니다. - 시스템 권한: 실행 시 사용자가
시스템 설정 > 개인정보 보호 및 보안 > 손쉬운 사용에서 해당 앱을 허용해야 이벤트가 전달됩니다.
2. 키 이벤트 생성 로직 (Swift 예시)
CGEvent를 사용하여 이벤트를 생성하고 post 함수로 시스템에 전달합니다.
import Foundation
import CoreGraphics
func pressControlOne() {
// 1. 키 코드 정의 (1 키의 가상 키 코드는 18)
let keyCode: CGKeyCode = 18
// 2. Key Down 이벤트 생성
let keyDown = CGEvent(keyboardEventSource: nil, virtualKey: keyCode, keyDown: true)
// 3. Control 키 플래그 추가
keyDown?.flags = .maskControl
// 4. Key Up 이벤트 생성
let keyUp = CGEvent(keyboardEventSource: nil, virtualKey: keyCode, keyDown: false)
keyUp?.flags = .maskControl // Up 이벤트에도 플래그를 유지하는 것이 안정적입니다.
// 5. 이벤트를 시스템(HID) 레벨로 전달
keyDown?.post(tap: .cghidEventTap)
keyUp?.post(tap: .cghidEventTap)
}
주요 구성 요소 설명
- CGKeyCode: 하드웨어 키의 고유 번호입니다. 숫자
1은18입니다. - CGEventFlags:
maskControl,maskShift,maskCommand등을 사용하여 조합 키를 구현합니다. - CGEventTapLocation:
.cghidEventTap을 사용하면 시스템 전체에 이벤트를 전송하며, 특정 프로세스에만 보내고 싶다면 해당 프로세스의PID를 이용해 이벤트를 제한할 수 있습니다.
3. 주의사항
- Main Thread: UI 버튼 클릭 시 이 로직이 실행되므로, 별도의 큐에서 실행할 필요는 없으나 이벤트 간의 미세한 지연이 필요한 경우
usleep등을 활용하기도 합니다. - Key Code 확인:
1외에 다른 키를 사용하려면 macOS 가상 키 코드 표를 참조하세요. (예:Tab은48,Enter는36)
이 코드를 버튼의 action 메서드 내에 배치하면 클릭 시 지정된 단축키가 동작하게 됩니다.
ENABLE_USER_SCRIPT_SANDBOXING = NO;