PyObjC MapKit Framework
pyobjc-framework-mapkit provides Python bindings for Apple's MapKit framework on macOS, enabling Python applications to integrate maps, display points of interest, and manage map data. It is part of the larger PyObjC project, currently at version 12.1, and follows a release cadence tied to macOS SDK updates and Python compatibility.
Warnings
- breaking PyObjC frequently drops support for older Python versions. PyObjC 12.0 dropped support for Python 3.9, and PyObjC 11.0 dropped support for Python 3.8. Always check the release notes for minimum Python requirements.
- breaking PyObjC 11.1 aligned its Automatic Reference Counting (ARC) semantics for Objective-C 'init' methods with `clang` documentation. This means 'init' methods now correctly steal a reference to `self` and return a new reference, which can affect memory management and object lifecycle if custom `__new__` or `__init__` methods are used without careful consideration.
- gotcha PyObjC 10.3 introduced changes to how `__init__` interacts with `__new__`. While `__init__` was initially disallowed for classes using PyObjC's `__new__`, version 10.3.1 reintroduced support for `__init__` when a user-defined `__new__` is present. However, code relying on the PyObjC-provided `__new__` still cannot use `__init__`.
- gotcha PyObjC introduced experimental support for Python 3.13's free-threading (PEP 703) in version 11.0. However, subsequent release notes (e.g., for v10.3, mentioning 3.13 support) clarified that PyObjC does *not* fully support free threading at this time. Attempting to use free-threading features with PyObjC may lead to undefined behavior or crashes.
- breaking PyObjC frameworks are closely tied to macOS SDKs. Older or deprecated frameworks may be removed from PyObjC bindings as they are removed from macOS itself. For instance, `IMServicePlugIn` bindings were removed in PyObjC 10.0 because the framework was deprecated in macOS 10.13 and removed in macOS 14.
Install
-
pip install pyobjc-framework-mapkit -
pip install pyobjc
Imports
- MKMapView
from MapKit import MKMapView
- CLLocationCoordinate2D
from MapKit import CLLocationCoordinate2D
- NSApplication
from AppKit import NSApplication
Quickstart
import objc
from AppKit import NSApplication, NSWindow, NSView, NSMakeRect, NSApp
from Foundation import NSObject
from MapKit import MKMapView, CLLocationCoordinate2D, MKCoordinateSpan, MKCoordinateRegion
class AppDelegate(NSObject):
def applicationDidFinishLaunching_(self, notification):
print("PyObjC MapKit Application Launched!")
# Create a window
self.window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer_(
NSMakeRect(100, 100, 800, 600),
(NSWindow.NSTitledWindowMask | NSWindow.NSClosableWindowMask | NSWindow.NSResizableWindowMask),
NSWindow.NSBackingStoreBuffered,
False
)
self.window.setTitle_("PyObjC MapKit Example")
# Create an MKMapView
self.mapView = MKMapView.alloc().initWithFrame_(self.window.contentView().frame())
self.mapView.setAutoresizingMask_(NSView.NSViewWidthSizable | NSView.NSViewHeightSizable)
# Define a location (e.g., San Francisco)
coordinate = CLLocationCoordinate2D(latitude=37.7749, longitude=-122.4194)
span = MKCoordinateSpan(latitudeDelta=0.1, longitudeDelta=0.1)
region = MKCoordinateRegion(center=coordinate, span=span)
self.mapView.setRegion_(region)
# Add the map view to the window
self.window.contentView().addSubview_(self.mapView)
self.window.makeKeyAndOrderFront_(None)
def applicationShouldTerminateAfterLastWindowClosed_(self, sender):
return True
# Initialize and run the application
app = NSApplication.sharedApplication()
delegate = AppDelegate.alloc().init()
app.setDelegate_(delegate)
NSApp.run()