{"id":6104,"library":"pyobjc-framework-externalaccessory","title":"PyObjC ExternalAccessory Framework","description":"PyObjC is a bridge between Python and the Objective-C runtime, allowing Python scripts to interact with macOS frameworks. The `pyobjc-framework-externalaccessory` package provides Python wrappers for the `ExternalAccessory` framework on macOS, enabling interaction with MFi (Made for iOS) accessories. The current version is 12.1, with releases tightly coupled to macOS SDK updates and Python version support cycles.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macos","objective-c","cocoa","bindings","mfi","hardware","external-accessory"],"install":[{"cmd":"pip install pyobjc-framework-externalaccessory","lang":"bash","label":"Install `ExternalAccessory` bindings"}],"dependencies":[{"reason":"Provides the core bridge between Python and Objective-C, essential for all PyObjC framework bindings.","package":"pyobjc-core"}],"imports":[{"note":"Framework symbols are typically imported directly under their framework name.","symbol":"ExternalAccessory","correct":"import ExternalAccessory"}],"quickstart":{"code":"import ExternalAccessory\nimport objc\n\ndef list_accessories():\n    manager = ExternalAccessory.EAAccessoryManager.sharedAccessoryManager()\n    accessories = manager.connectedAccessories()\n\n    if accessories:\n        print(f\"Found {len(accessories)} connected accessories:\")\n        for acc in accessories:\n            print(f\"  - Name: {acc.name()}\")\n            print(f\"    Model Number: {acc.modelNumber()}\")\n            print(f\"    Manufacturer: {acc.manufacturer()}\")\n            print(f\"    Serial Number: {acc.serialNumber()}\")\n            print(f\"    Firmware Revision: {acc.firmwareRevision()}\")\n            print(f\"    Hardware Revision: {acc.hardwareRevision()}\")\n            print(f\"    Protocol Strings: {acc.protocolStrings()}\")\n    else:\n        print(\"No MFi accessories connected.\")\n\n# Note: EAAccessoryManager typically requires an active runloop or\n# an application context to correctly detect accessories and receive notifications.\n# For simple scripting, you might need to run a console event loop.\n# import PyObjCTools.AppHelper\n# PyObjCTools.AppHelper.runConsoleEventLoop(installInterrupt=True, mode=objc.NSDefaultRunLoopMode, untilIdle=True)\n\nif __name__ == '__main__':\n    # This part runs the list_accessories function immediately.\n    # In a full Cocoa app, this would be part of a delegate or controller.\n    # For a simple script, it will just check at startup.\n    list_accessories()","lang":"python","description":"This quickstart demonstrates how to access the shared `EAAccessoryManager` and list currently connected MFi accessories. While this code runs, full interaction with `ExternalAccessory` (e.g., establishing communication sessions, receiving notifications) often requires an active Cocoa event loop and proper application lifecycle management, which is typically handled by `PyObjCTools.AppHelper` in more complex PyObjC applications."},"warnings":[{"fix":"Upgrade your Python version to 3.10 or newer, or downgrade PyObjC to a compatible version if sticking with an older Python.","message":"PyObjC aggressively drops support for older Python versions. Version 12.0 dropped Python 3.9, and version 11.0 dropped Python 3.8. Ensure your Python environment meets the `requires_python` specification (currently `>=3.10` for v12.1).","severity":"breaking","affected_versions":">=11.0"},{"fix":"Review custom Python subclasses that override Objective-C initializer methods to ensure correct reference handling, especially when dealing with manually managed references or complex initialization patterns. Consult PyObjC's documentation on memory management.","message":"The core bridge's Automatic Reference Counting (ARC) behavior for initializer methods (those in the 'init' family) was updated in `v11.1` to align with `clang`'s documentation. This means PyObjC now correctly models that `init` methods steal a reference to `self` and return a new reference, potentially affecting custom `init` methods in Python subclasses.","severity":"breaking","affected_versions":">=11.1"},{"fix":"Ensure your development and deployment environment is macOS. Use conditional imports or platform checks (`sys.platform == 'darwin'`) if your application needs to support multiple operating systems.","message":"PyObjC is a macOS-specific library. It binds directly to Objective-C frameworks available only on Apple's macOS operating system. Attempts to install or run PyObjC code on Linux, Windows, or other platforms will fail with import errors or linker issues.","severity":"gotcha","affected_versions":"all"},{"fix":"If implementing custom `__new__` in Python subclasses of ObjC objects, ensure `__init__` is correctly called and interacts with the PyObjC bridge as expected. For classes using PyObjC's default `__new__`, initialization logic must reside in other designated setup methods.","message":"Behavior around `__init__` and `__new__` methods in Python subclasses of Objective-C objects changed in `v10.3` and was partially reverted in `v10.3.1`. While `__init__` can now be used when a user implements `__new__`, code relying on the PyObjC-provided `__new__` still cannot use `__init__` for custom initialization logic.","severity":"gotcha","affected_versions":">=10.3"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}