🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 1 Min Lesezeit
0

macOSのInput Monitoring判定で、2つのAPIと「実際に動くか」を分けて観察する

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

macOSでグローバルなキーイベントを受け取るアプリを作ると、権限判定を単純な Bool として扱いたくなります。しかし実装と検証を進めるほど、次の3つは分けて考えた方が安全でした。




  1. TCC上で権限がどう見えているか

  2. ユーザーへ権限を要求した直後か


  3. CGEvent.tapCreate が実際に成功し、イベントを受け取れるか



この記事では、macOS向け打鍵音アプリを作る過程で使った診断方法を、製品固有のUIから切り離して整理します。






2つの事前確認API



Listen-onlyのイベント監視では、次の2つを並べて観察できます。




CODE
import CoreGraphics
import IOKit.hidsystem

struct InputMonitoringStatus {
let hid: IOHIDAccessType
let cgGranted: Bool

var looksGranted: Bool {
hid == kIOHIDAccessTypeGranted || cgGranted
}
}

func readInputMonitoringStatus() -> InputMonitoringStatus {
InputMonitoringStatus(
hid: IOHIDCheckAccess(kIOHIDRequestTypeListenEvent),
cgGranted: CGPreflightListenEventAccess()
)
}






ここで重要なのは、looksGranted を「監視が必ず動く」という保証にしないことです。これはあくまで事前状態の観察結果です。プロセス、署名、実行パス、権限変更直後の状態などを切り分けるために、2つの値を別々にログへ残します。



ログへ記録するなら、入力内容ではなく次のような診断情報だけで十分です。




CODE
bundle_id=com.example.app
hid_status=granted
cg_preflight=true
event_tap_created=true






キーコード、入力文字列、前後のアプリ名まで診断ログへ入れる必要はありません。






権限要求は「確認」と分ける



要求側のAPIは、確認のたびに呼ぶのではなく、初回案内やユーザーが明示的に「権限を開く」を選んだ時だけ呼びます。




CODE
func requestInputMonitoring() {
let hidRequested = IOHIDRequestAccess(kIOHIDRequestTypeListenEvent)
let cgRequested = CGRequestListenEventAccess()

let current = readInputMonitoringStatus()
print("hidRequested=\(hidRequested), cgRequested=\(cgRequested)")
print("looksGranted=\(current.looksGranted)")
}






要求APIの戻り値だけで次の画面を決めると、ユーザーがシステム設定へ移動して後から許可した場合を扱いにくくなります。要求後は、アプリ側の状態を次のように分けました。





  • notRequested: まだ案内していない


  • waitingForUser: システム設定での操作待ち


  • preflightGranted: 事前確認では許可済み


  • monitoring: Event Tapが作成され、監視中


  • revoked: 監視中に権限を失った






最終判定はEvent Tapの生成結果



事前確認が通っていても、Event Tapの作成失敗は別の事実として扱います。




CODE
let mask = (1 << CGEventType.keyDown.rawValue)
| (1 << CGEventType.keyUp.rawValue)
| (1 << CGEventType.flagsChanged.rawValue)

let tap = CGEvent.tapCreate(
tap: .cgSessionEventTap,
place: .headInsertEventTap,
options: .listenOnly,
eventsOfInterest: CGEventMask(mask),
callback: callback,
userInfo: context
)

guard let tap else {
// 権限表示だけでなく、署名・実行パス・再起動要否も切り分ける
return
}






.listenOnly はイベントを書き換えない設計を表せますが、プライバシー説明の代わりにはなりません。アプリが何を処理し、何を保存せず、何を外部送信しないのかは別途明記する必要があります。






権限変更をポーリングする場合



システム設定を開いた後にアプリへ戻ってもらう導線では、短い間隔で状態を再確認する実装が分かりやすいです。ただし、次の境界を決めておきます。




  • Timerを重複生成しない

  • 監視開始後は要求用Timerを停止する

  • 権限喪失時はEvent TapとRunLoop Sourceを破棄する

  • 復旧時はユーザー設定が有効な場合だけ監視を再開する

  • アプリ終了時はTimerも明示的に破棄する



「権限がある」と「監視中」を同じフラグにすると、権限喪失後のUIと実体がずれやすくなります。権限状態、Event Tapの生存状態、ユーザーが機能をオンにしているかを別々に持つ方が復旧処理を書きやすくなりました。






まとめ





  • IOHIDCheckAccessCGPreflightListenEventAccess は診断のため別々に観察する

  • 要求APIは確認ループから分離し、ユーザー操作に結び付ける

  • 事前確認が通っていても、Event Tap生成結果を最終的な動作判定にする

  • 権限、監視状態、ユーザー設定を別の状態として管理する

  • 入力内容を診断ログやAnalyticsへ混ぜない






この記事は、macOS向け打鍵音アプリ Klakk の開発チームが、実装中に得た知見を一般化してまとめたものです。自社の有料製品へのリンクを含みます。





Klakkは物理キーコードと押下・解放状態をローカルで処理し、入力文字列を組み立てたり送信したりしません。ソフトウェアの音を追加する製品であり、物理キーボード自体の音や打鍵感は変えません。

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage