{"id":6179,"library":"pyobjc-framework-speech","title":"PyObjC Speech Framework","description":"PyObjC-framework-Speech provides Python wrappers for the macOS Speech framework, enabling features like speech recognition. It's part of the PyObjC project, which bridges Python and Objective-C, and typically updates alongside macOS SDK releases, ensuring compatibility with the latest system features.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macos","speech recognition","framework wrapper","objective-c bridge","apple","pyobjc"],"install":[{"cmd":"pip install pyobjc-framework-speech","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"PyObjC-framework-Speech is a binding for a macOS framework and requires the core PyObjC bridge to function.","package":"pyobjc-core","optional":false}],"imports":[{"symbol":"SFSpeechRecognizer","correct":"from Speech import SFSpeechRecognizer"},{"symbol":"SFSpeechRecognitionRequest","correct":"from Speech import SFSpeechRecognitionRequest"},{"symbol":"SFSpeechRecognizerAuthorizationStatusAuthorized","correct":"from Speech import SFSpeechRecognizerAuthorizationStatusAuthorized"},{"symbol":"NSLocale","correct":"from Foundation import NSLocale"}],"quickstart":{"code":"import objc\nfrom Foundation import NSLog, NSLocale\nfrom Speech import SFSpeechRecognizer, SFSpeechRecognizerAuthorizationStatusAuthorized, SFSpeechRecognizerAuthorizationStatusNotDetermined\n\ndef check_speech_recognizer_availability():\n    # Check authorization status\n    status = SFSpeechRecognizer.authorizationStatus()\n    if status == SFSpeechRecognizerAuthorizationStatusNotDetermined:\n        NSLog(\"Speech recognition authorization status: Not Determined. Requesting access...\")\n        # This will present a permission dialog to the user. The callback will be invoked.\n        # In a full app, you'd handle the response asynchronously.\n        SFSpeechRecognizer.requestAuthorization_(lambda new_status: NSLog(f\"New authorization status: {new_status}\"))\n    elif status != SFSpeechRecognizerAuthorizationStatusAuthorized:\n        NSLog(f\"Speech recognition authorization denied or restricted: {status}\")\n        return\n\n    # Create a recognizer for the default locale\n    recognizer = SFSpeechRecognizer.alloc().init()\n    if recognizer:\n        NSLog(f\"SFSpeechRecognizer available: {recognizer.isAvailable()}\")\n        NSLog(f\"Supported locales: {[locale.localeIdentifier() for locale in recognizer.supportedLocales()]}\")\n    else:\n        NSLog(\"Failed to create SFSpeechRecognizer. Ensure device supports speech recognition.\")\n\nif __name__ == \"__main__\":\n    # For permission requests to fully process and callbacks to fire reliably in a script,\n    # a Cocoa event loop is often necessary.\n    check_speech_recognizer_availability()\n    # For interactive scripts, uncomment the following lines to run a small event loop:\n    # from PyObjCTools import AppHelper\n    # AppHelper.runConsoleEventLoop(installInterrupt=True)","lang":"python","description":"Checks the authorization status for speech recognition, requests it if not determined, and then initializes an `SFSpeechRecognizer` to check its availability and supported locales. Note that a full PyObjC application typically runs within an event loop to handle UI interactions and asynchronous callbacks properly. Running this script directly will trigger the permission dialog, but a `PyObjCTools.AppHelper.runConsoleEventLoop` might be needed for the callback to be fully processed if the script exits too quickly."},"warnings":[{"fix":"Upgrade to Python 3.10 or newer (Python 3.13 is supported by recent PyObjC releases, with experimental free-threading).","message":"PyObjC 12.0 dropped support for Python 3.9. PyObjC 11.0 dropped support for Python 3.8. Users must use newer Python versions to install and run these PyObjC releases.","severity":"breaking","affected_versions":"11.0, 12.0+"},{"fix":"Implement `SFSpeechRecognizer.requestAuthorization_` and handle its callback. Crucially, ensure your app's `Info.plist` (for bundled apps) includes `NSSpeechRecognitionUsageDescription` and `NSMicrophoneUsageDescription` keys with descriptive strings.","message":"Using the macOS Speech framework (and many other macOS frameworks) requires explicit user permissions (e.g., microphone access, speech recognition). Your application must request these permissions, and users must grant them.","severity":"gotcha","affected_versions":"all"},{"fix":"Update imports from `AVFoundation` to `AVFAudio` for specific audio components. Ensure `pyobjc-framework-AVFoundation` is installed if you need the `AVFAudio` components (it is included in that distribution).","message":"PyObjC 12.0 introduced a significant change by splitting the `AVFAudio` bindings into their own top-level package, instead of being merged into `AVFoundation`. While `pyobjc-framework-speech` imports directly from `Speech`, projects using multiple PyObjC bindings, especially those involving audio, might be affected.","severity":"breaking","affected_versions":"12.0+"},{"fix":"Review memory management patterns, especially around object creation and initialization, for code interacting deeply with Objective-C objects via `alloc().init()` and similar patterns.","message":"PyObjC 11.1 aligned its core bridge behavior with clang's Automatic Reference Counting (ARC) documentation for initializer methods. This means methods in the 'init' family now correctly steal a reference to self and return a new one, which might change memory management expectations for advanced users interacting directly with Objective-C object lifecycles.","severity":"gotcha","affected_versions":"11.1+"},{"fix":"Familiarize yourself with Cocoa's delegate pattern. For command-line tools or scripts, consider using `PyObjCTools.AppHelper.runConsoleEventLoop()` to ensure callbacks are processed and permission dialogs are handled correctly.","message":"Speech recognition with `SFSpeechRecognizer` is an inherently asynchronous process using delegates and callbacks, which is different from typical synchronous Python APIs. Proper handling often requires running within a Cocoa event loop.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}