{"id":5025,"library":"pyobjc-framework-vision","title":"PyObjC Vision Framework","description":"pyobjc-framework-vision provides Python wrappers for Apple's Vision framework on macOS. It is part of the PyObjC project, a bidirectional bridge enabling Python scripts to interact with Objective-C libraries, including macOS Cocoa frameworks. The current version is 12.1 and it maintains an active release cadence, typically aligning with macOS SDK updates and Python version support.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macOS","Apple Vision Framework","Computer Vision","Objective-C bridge","PyObjC"],"install":[{"cmd":"pip install pyobjc-framework-vision","lang":"bash","label":"Install pyobjc-framework-vision"}],"dependencies":[{"reason":"Core bridge for Python and Objective-C, required for all pyobjc-framework-* packages.","package":"pyobjc-core"},{"reason":"Often implicitly required for core macOS types like NSURL, NSImage, and other fundamental classes used by Vision framework components.","package":"pyobjc-framework-Cocoa","optional":true},{"reason":"Provides core data types and classes, frequently used with Vision framework operations (e.g., NSDictionary, NSURL).","package":"pyobjc-framework-Foundation","optional":true},{"reason":"Required for CIImage when handling images, which is common in Vision framework tasks.","package":"pyobjc-framework-Quartz","optional":true}],"imports":[{"note":"The primary import for accessing the Vision framework classes and functions.","symbol":"Vision","correct":"import Vision"},{"note":"Many core Objective-C classes, like NSURL or NSDictionary, reside in the Cocoa or Foundation frameworks, not directly in Vision.","wrong":"import NSURL","symbol":"NSURL","correct":"from Cocoa import NSURL"},{"note":"Similar to NSURL, core data structures are typically found in Foundation.","wrong":"import NSDictionary","symbol":"NSDictionary","correct":"from Foundation import NSDictionary"}],"quickstart":{"code":"import os\nimport Vision\nfrom Foundation import NSURL, NSDictionary\nfrom Cocoa import CIImage # Often found in Quartz, but CIImage is exposed via Cocoa as well for convenience\n\ndef recognize_text_in_image(image_path):\n    if not os.path.exists(image_path):\n        print(f\"Error: Image not found at {image_path}\")\n        return\n\n    # Convert Python path to NSURL\n    input_url = NSURL.fileURLWithPath_(image_path)\n\n    # Create CIImage from the URL\n    input_image = CIImage.imageWithContentsOfURL_(input_url)\n    if input_image is None:\n        print(f\"Error: Could not create CIImage from {image_path}\")\n        return\n\n    # Create a Vision request handler\n    vision_options = NSDictionary.dictionaryWithDictionary_({})\n    vision_handler = Vision.VNImageRequestHandler.alloc().initWithCIImage_options_(\n        input_image, vision_options\n    )\n\n    # Prepare a text recognition request\n    results = []\n    def completion_handler(request, error):\n        if error:\n            print(f\"Vision request error: {error}\")\n        else:\n            for observation in request.results():\n                if isinstance(observation, Vision.VNRecognizedTextObservation):\n                    for text_candidate in observation.topCandidates_(1):\n                        results.append(text_candidate.string())\n\n    text_request = Vision.VNRecognizeTextRequest.alloc().initWithCompletionHandler_(\n        completion_handler\n    )\n    \n    # Perform the request\n    error_ptr = None # PyObjC expects None for output pointers that aren't being used for input\n    success, error = vision_handler.performRequests_error_([text_request], error_ptr)\n\n    if not success:\n        print(f\"Failed to perform Vision request: {error}\")\n    \n    return results\n\n# Example usage:\n# Create a dummy image file for demonstration\n# In a real scenario, replace this with a path to an actual image file.\n# For a real image with text, you might create one using Pillow or similar.\ndummy_image_path = os.environ.get('VISION_TEST_IMAGE_PATH', 'dummy_image_with_text.png')\nif not os.path.exists(dummy_image_path):\n    print(f\"Please set VISION_TEST_IMAGE_PATH or create a file named '{dummy_image_path}' to run this example.\")\n    print(\"Example: create a simple PNG with some text using an image editor.\")\nelse:\n    print(f\"Analyzing image: {dummy_image_path}\")\n    detected_text = recognize_text_in_image(dummy_image_path)\n    if detected_text:\n        print(\"Detected text:\")\n        for text in detected_text:\n            print(f\"- {text}\")\n    else:\n        print(\"No text detected or an error occurred.\")","lang":"python","description":"This quickstart demonstrates how to use `pyobjc-framework-vision` to perform text recognition on an image. It showcases the typical pattern of loading an image, creating a Vision request handler, defining a request, and processing the results. A dummy image path is used for a runnable example; replace it with a path to an actual image for real-world testing."},"warnings":[{"fix":"Upgrade your Python environment to Python 3.10 or later for PyObjC 12.x. Always check `requires_python` on PyPI or the PyObjC changelog for specific version requirements.","message":"PyObjC frequently drops support for older Python versions. PyObjC 12.0 dropped support for Python 3.9, and PyObjC 11.0 dropped Python 3.8. Ensure your Python version is compatible with the PyObjC version you are installing.","severity":"breaking","affected_versions":">=11.0"},{"fix":"Review code that interacts with object initialization, especially custom subclasses or factory methods, to ensure correct reference handling. Explicit memory management is rarely needed in Python, but understanding the underlying Objective-C semantics is crucial for correct behavior.","message":"PyObjC 11.1 changed how initializer methods (`init` family) are modeled, now correctly reflecting that they 'steal' a reference to `self` and return a new one, as per clang's ARC documentation. This affects object lifecycle and reference counting.","severity":"breaking","affected_versions":">=11.1"},{"fix":"Always check for `None` before calling methods on PyObjC-wrapped objects that might originate from Objective-C `nil` values. E.g., `if my_obj is not None: my_obj.doSomething_()`","message":"Unlike Objective-C, where sending a message to `nil` (equivalent to Python `None`) is a no-op, attempting to call a method on a Python `None` object (which PyObjC translates from `nil`) will raise an `AttributeError`.","severity":"gotcha","affected_versions":"All"},{"fix":"Only use `pyobjc-framework-vision` in macOS environments. For cross-platform computer vision, consider libraries like OpenCV.","message":"PyObjC is a macOS-specific library and will not install or run on other operating systems. The frameworks it wraps (like Vision) are Apple-proprietary.","severity":"gotcha","affected_versions":"All"},{"fix":"Familiarize yourself with Objective-C naming conventions and PyObjC's translation rules to correctly call methods and implement Objective-C protocols in Python. Refer to the 'Underscores, and lots of them' section in the PyObjC documentation.","message":"When implementing custom Objective-C subclasses in Python, the Objective-C method names (selectors) containing colons (`:`) are translated to Python method names with underscores (`_`). For example, `doSomething:withSomethingElse:` becomes `doSomething_withSomethingElse_`.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}