{"library":"pyobjc-framework-corelocation","title":"CoreLocation Framework for PyObjC","description":"pyobjc-framework-corelocation provides Python wrappers for Apple's CoreLocation 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. This framework offers interfaces for obtaining a machine's physical location, allowing for geo-aware applications. The current version is 12.1 and it maintains an active release cadence, typically aligning with macOS SDK updates and Python version support.","language":"python","status":"active","last_verified":"Sat May 16","install":{"commands":["pip install pyobjc-framework-corelocation"],"cli":null},"imports":["import CoreLocation"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import objc\nfrom CoreLocation import CLGeocoder\nfrom Foundation import NSRunLoop, NSDate, NSObject\nimport time\n\n\nclass GeocoderDelegate(NSObject):\n    # This is a delegate class to handle geocoding results asynchronously.\n    # In a real application, you might use a more robust threading/event loop setup.\n    def init(self):\n        self = super(GeocoderDelegate, self).init()\n        if not self: return None\n        self.results = {\"placemarks\": [], \"error\": None}\n        self.completed = False\n        return self\n\n    def geocoder_didGeocodePlacemarks_error_(self, geocoder, placemarks, error):\n        if error:\n            self.results[\"error\"] = error.localizedDescription()\n        elif placemarks:\n            self.results[\"placemarks\"] = placemarks\n        self.completed = True\n\ndef forward_geocode(address: str) -> list[dict]:\n    with objc.autorelease_pool():\n        geocoder = CLGeocoder.alloc().init()\n        delegate = GeocoderDelegate.alloc().init()\n        \n        # Call the Objective-C method with a Python delegate\n        geocoder.geocodeAddressString_completionHandler_(address, \n            lambda placemarks, error: delegate.geocoder_didGeocodePlacemarks_error_(geocoder, placemarks, error))\n\n        # Keep the runloop active until the geocoding is complete\n        # This is a blocking loop for demonstration; for GUI apps, the main runloop handles this.\n        timeout = time.time() + 10  # 10-second timeout\n        while not delegate.completed and time.time() < timeout:\n            NSRunLoop.currentRunLoop().runMode_beforeDate_(\n                \"NSDefaultRunLoopMode\", NSDate.dateWithTimeIntervalSinceNow_(0.1)\n            )\n        \n        if not delegate.completed:\n            raise TimeoutError(\"Geocoding request timed out.\")\n\n        if delegate.results[\"error\"]:\n            raise Exception(f\"Geocoding error: {delegate.results['error']}\")\n\n        formatted_results = []\n        for pm in delegate.results[\"placemarks\"]:\n            loc = pm.location()\n            if loc:\n                coord = loc.coordinate()\n                formatted_results.append({\n                    \"latitude\": coord.latitude,\n                    \"longitude\": coord.longitude,\n                    \"name\": pm.name(),\n                    \"locality\": pm.locality(),\n                    \"country\": pm.country()\n                })\n        return formatted_results\n\nif __name__ == \"__main__\":\n    try:\n        locations = forward_geocode(\"1 Infinite Loop, Cupertino, CA\")\n        if locations:\n            print(\"\\nLocation found:\")\n            for loc in locations:\n                for key, value in loc.items():\n                    if value:\n                        print(f\"  {key}: {value}\")\n        else:\n            print(\"No locations found.\")\n    except Exception as e:\n        print(f\"Error: {e}\")","lang":"python","description":"This quickstart demonstrates how to perform forward geocoding using `CLGeocoder` from the `CoreLocation` framework. It shows the typical PyObjC pattern of initializing Objective-C objects, setting up a Python delegate to handle asynchronous callbacks, and running a `NSRunLoop` to process events until the operation completes. Note that CoreLocation APIs require network access for geocoding and user permission prompts on macOS.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-16","installed_version":null,"pypi_latest":"12.1","is_stale":null,"summary":{"python_range":"3.10–3.9","success_rate":0,"avg_install_s":null,"avg_import_s":null,"wheel_type":null},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":2.9,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":2.9,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":2.9,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":2.5,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pyobjc-framework-corelocation","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":3.4,"import_time_s":null,"mem_mb":null,"disk_size":null}]}}