PyObjC ScriptingBridge Framework
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.
Warnings
- breaking 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).
- breaking 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.
- gotcha 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.
- gotcha 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.
- gotcha 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.
Install
-
pip install pyobjc-framework-scriptingbridge -
pip install pyobjc
Imports
- SBApplication
from ScriptingBridge import SBApplication
Quickstart
from ScriptingBridge import SBApplication
from AppKit import NSWorkspace # NSWorkspace can be used to check if an app is running
def get_itunes_track_name():
# Get a reference to iTunes (or Music app on newer macOS)
try:
itunes = SBApplication.applicationWithBundleIdentifier_("com.apple.itunes")
except Exception:
# On macOS Catalina and later, iTunes was replaced by the Music app.
# ScriptingBridge might still reference 'itunes', but bundle ID changed.
itunes = SBApplication.applicationWithBundleIdentifier_("com.apple.Music")
if itunes and itunes.isRunning():
current_track = itunes.currentTrack()
if current_track:
return f"iTunes/Music is playing: {current_track.name()}"
else:
return "iTunes/Music is running, but no track is playing."
else:
return "iTunes/Music is not running."
if __name__ == "__main__":
print(get_itunes_track_name())