{"id":6167,"library":"pyobjc-framework-scriptingbridge","title":"PyObjC ScriptingBridge Framework","description":"PyObjC provides Python bindings for macOS frameworks, allowing Python applications to interact with Objective-C APIs. `pyobjc-framework-scriptingbridge` specifically offers wrappers for the ScriptingBridge framework, enabling Python to control scriptable applications on macOS. The library is currently at version 12.1 and typically releases alongside major macOS SDK updates and Python version support changes.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macos","objective-c","cocoa","scriptingbridge","automation","gui"],"install":[{"cmd":"pip install pyobjc-framework-scriptingbridge","lang":"bash","label":"Install only ScriptingBridge bindings"},{"cmd":"pip install pyobjc","lang":"bash","label":"Install all PyObjC frameworks (recommended)"}],"dependencies":[{"reason":"This package provides the core bridge between Python and Objective-C. All `pyobjc-framework-*` packages depend on it implicitly.","package":"pyobjc-core"}],"imports":[{"note":"ScriptingBridge classes are typically imported directly from the `ScriptingBridge` module.","symbol":"SBApplication","correct":"from ScriptingBridge import SBApplication"}],"quickstart":{"code":"from ScriptingBridge import SBApplication\nfrom AppKit import NSWorkspace # NSWorkspace can be used to check if an app is running\n\ndef get_itunes_track_name():\n    # Get a reference to iTunes (or Music app on newer macOS)\n    try:\n        itunes = SBApplication.applicationWithBundleIdentifier_(\"com.apple.itunes\")\n    except Exception:\n        # On macOS Catalina and later, iTunes was replaced by the Music app.\n        # ScriptingBridge might still reference 'itunes', but bundle ID changed.\n        itunes = SBApplication.applicationWithBundleIdentifier_(\"com.apple.Music\")\n\n    if itunes and itunes.isRunning():\n        current_track = itunes.currentTrack()\n        if current_track:\n            return f\"iTunes/Music is playing: {current_track.name()}\"\n        else:\n            return \"iTunes/Music is running, but no track is playing.\"\n    else:\n        return \"iTunes/Music is not running.\"\n\nif __name__ == \"__main__\":\n    print(get_itunes_track_name())\n","lang":"python","description":"This quickstart demonstrates how to use `ScriptingBridge` to interact with the Music app (or iTunes on older macOS) to check if it's running and retrieve the name of the currently playing track. It showcases `SBApplication` for referencing scriptable applications by their bundle identifier."},"warnings":[{"fix":"Upgrade your Python environment to 3.10 or newer, or pin your `pyobjc` dependency to an older version that supports your Python version.","message":"PyObjC versions frequently drop support for older Python versions. PyObjC 12.0 dropped Python 3.9 support, and 11.0 dropped Python 3.8. Ensure your Python environment meets the `requires_python` spec (currently `>=3.10` for v12.1).","severity":"breaking","affected_versions":">=11.0"},{"fix":"Review code that directly calls Objective-C `init` family methods (e.g., `alloc().init()`) or custom Objective-C classes exposed to Python. Ensure proper reference handling and avoid premature deallocation.","message":"PyObjC 11.1 aligned the core bridge's behavior with `clang`'s documentation for Automatic Reference Counting (ARC) regarding initializer methods. Methods in the 'init' family now correctly steal a reference to self and return a new reference, which can subtly change object lifecycle and memory management in Python code that directly interacts with Objective-C initializers.","severity":"breaking","affected_versions":">=11.1"},{"fix":"When using Python 3.13 with `pyobjc` in a free-threaded build, thoroughly test your application for stability and correctness. Report any issues to the PyObjC project. For critical applications, consider sticking to non-free-threaded Python builds until the feature is stable.","message":"PyObjC 11.0 introduced *experimental* support for free-threading (PEP 703) with Python 3.13. While promising, this is an experimental feature and might have stability or performance implications that are not fully mature. Use with caution in production environments.","severity":"gotcha","affected_versions":">=11.0 (Python 3.13+)"},{"fix":"If you define Python subclasses of Objective-C objects that implement `__new__`, ensure your `__init__` methods are correctly called and behave as expected, especially if migrating from versions prior to 10.3. Test class instantiation thoroughly.","message":"The behavior of `__init__` when a Python class (or its superclass) implements `__new__` was changed in PyObjC 10.3 (disallowing `__init__`) and then partially reverted in 10.3.1 to reintroduce `__init__` support under those conditions. This can affect how you define Objective-C proxy classes in Python.","severity":"gotcha","affected_versions":"10.3, >=10.3.1"},{"fix":"If you have Python-defined `NSProxy` subclasses that were implicitly using KVO, you may need to re-evaluate their design or implement manual observation mechanisms, as automatic KVO is now disabled for them.","message":"PyObjC 12.1 automatically disables Key-Value Observing (KVO) usage for subclasses of `NSProxy` defined in Python. If your application relies on KVO for custom `NSProxy` subclasses, their behavior might change unexpectedly.","severity":"gotcha","affected_versions":">=12.1"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}