PyObjC: IOSurface Framework
PyObjC is a bridge between Python and Objective-C, enabling Python scripts to interact with and extend macOS's Cocoa libraries and other Objective-C frameworks. The `pyobjc-framework-iosurface` package provides Python wrappers specifically for Apple's IOSurface framework, which allows applications to share graphics buffers efficiently across processes. It is actively maintained, with version 12.1 being the latest, and sees regular updates to support new macOS SDKs and Python versions.
Warnings
- breaking PyObjC 12.0 dropped support for Python 3.9, and PyObjC 11.0 dropped support for Python 3.8. Users must ensure their Python version meets the `requires_python` specification (currently >=3.10) to use recent PyObjC versions.
- breaking PyObjC 11.1 introduced a significant change in how initializer methods (those in the 'init' family) handle object references, aligning with `clang`'s Automatic Reference Counting (ARC) documentation. This means `init` methods are now correctly modeled to steal a reference to `self` and return a new one.
- gotcha PyObjC translates Objective-C selectors (method names) with embedded colons (e.g., `doSomething:withSomethingElse:`) into Python method names where colons are replaced by underscores (e.g., `doSomething_withSomethingElse_`). Each underscore indicates an argument.
- gotcha In PyObjC 10.3, behavior around `__init__` when a user implements `__new__` was modified, potentially breaking some popular projects. Version 10.3.1 partially reverted this, reintroducing the ability to use `__init__` if `__new__` is user-implemented. However, code relying on PyObjC's provided `__new__` still cannot use `__init__` for reasons explained in the 10.3 release notes.
- deprecated PyObjC 10.0 removed bindings for the `IMServicePlugIn` framework as the framework itself was deprecated in macOS 10.13 and removed in macOS 14. This indicates a general trend where bindings for deprecated macOS frameworks may be removed in future PyObjC releases.
Install
-
pip install pyobjc-framework-iosurface -
pip install pyobjc # Installs all framework bindings
Imports
- IOSurface
import IOSurface
Quickstart
import IOSurface
# Define properties for the IOSurface
# PyObjC automatically bridges Python dictionaries to CFDictionary
# and Python integers/booleans to CFNumber/CFBoolean.
properties = {
IOSurface.kIOSurfaceWidth: 640,
IOSurface.kIOSurfaceHeight: 480,
IOSurface.kIOSurfaceBytesPerElement: 4, # e.g., 4 bytes per pixel for 32-bit color
IOSurface.kIOSurfacePixelFormat: 0x42524741, # Example: 'ARGB' (Big-endian equivalent)
# IOSurface.kIOSurfaceBytesPerRow: 640 * 4, # Can be derived or explicitly set
}
# Create the IOSurface
surface = IOSurface.IOSurfaceCreate(properties)
if surface:
print(f"Successfully created IOSurface: {surface}")
print(f"IOSurface ID: {IOSurface.IOSurfaceGetID(surface)}")
print(f"IOSurface Width: {IOSurface.IOSurfaceGetWidth(surface)}")
print(f"IOSurface Height: {IOSurface.IOSurfaceGetHeight(surface)}")
# The 'surface' object's memory is managed by Objective-C's ARC,
# but the Python wrapper will be garbage collected.
else:
print("Failed to create IOSurface.")