Safe Rust bindings for Apple's MapKit framework on macOS.
Status: v0.3.0 adds an executor-agnostic
asyncfeature (Tier-1 async API) on top of full audited coverage for the non-exempt macOS 26.2 MapKit SDK surface.
use mapkit::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let map_view = MKMapView::new(MKScreenSize::new(320.0, 240.0))?;
let center = MKCoordinate::new(37.3349, -122.0090);
let region = MKCoordinateRegion::with_distance(center, 2_000.0, 2_000.0)?;
map_view.set_region(region, false)?;
let annotation = MKPointAnnotation::new(center)?;
annotation.set_title(Some("Apple Park"))?;
map_view.add_point_annotation(&annotation)?;
println!("annotations={}", map_view.annotation_count()?);
Ok(())
}Enable the async Cargo feature for executor-agnostic [Future][std::future::Future] wrappers
around MapKit's completion-handler APIs (works with Tokio, async-std, smol,
pollster, …):
[dependencies]
mapkit = { version = "0.3", features = ["async"] }# #[cfg(feature = "async")]
# fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(async {
use mapkit::async_api::{AsyncMKLocalSearch, AsyncMKDirections};
use mapkit::local_search::MKLocalSearchRequest;
// Async local search
let response = AsyncMKLocalSearch::search(
&MKLocalSearchRequest::new("coffee")
)?.await?;
println!("Found {} results", response.map_items.len());
# Ok(()) }) }
# #[cfg(not(feature = "async"))]
# fn main() {}| Type | Maps to |
|---|---|
AsyncMKLocalSearch |
MKLocalSearch.start(completionHandler:) |
AsyncMKDirections |
MKDirections.calculate / calculateETA |
AsyncMKMapSnapshotter |
MKMapSnapshotter.start(completionHandler:) |
AsyncMKGeocodingRequest |
MKGeocodingRequest.getMapItems (macOS 26.0+) |
AsyncMKReverseGeocodingRequest |
MKReverseGeocodingRequest.getMapItems (macOS 26.0+) |
Note:
MKLocalSearchandMKDirectionsdispatch their callbacks on the main queue; the main run loop must be active for those futures to resolve.MKMapSnapshotteruses a background queue and has no such restriction.Multi-fire delegate surfaces (
MKLocalSearchCompleter,MKMapViewDelegate) are deferred to a Tier-2 Stream rollout.
MKMapViewcreation, region/map-rect conversions, interaction toggles, camera boundaries/zoom ranges, preferred configurations, generic annotations/overlays, default reuse identifiers, and user tracking modeMKPointAnnotation,MKMapItemAnnotation,MKUserLocation,MKAnnotationView,MKMarkerAnnotationView,MKPinAnnotationView,MKUserLocationView,MKClusterAnnotation,MKCircle,MKPolyline,MKMultiPolyline,MKPolygon,MKMultiPolygon,MKTileOverlay, and overlay renderersMKLocalSearch,MKLocalSearchCompleter, andMKDirectionsrequest/response bridges for search and routing servicesMKMapSnapshotterandMKLookAroundSnapshotterwrappers for headless image generationMKGeocodingRequestandMKReverseGeocodingRequeston macOS 26+MKPointOfInterestFilter,MKLocalPointsOfInterestRequest, the fullMKPointOfInterestCategoryconvenience set,MKAddress, andMKAddressFilterMKMapItem/MKPlacemarkdata models, launch-option constants,MKMapItemIdentifier,MKMapItemRequest, andMKErrorCode/MKErrorDomainhelpersMKGeoJSONDecoderplus the full auditedMKGeometry.hhelper surface, and headless-safe Rust models/traits for map controls, selection accessories, map-item detail / Look Around controllers, andMKMapViewDelegate
This crate ships numbered, headless-safe examples for every logical area:
cargo run --example 01_mapkit_smoke
cargo run --example 15_configuration_camera
cargo run --example 17_annotation_view_basic
cargo run --example 18_overlay_renderer_basic
cargo run --example 19_points_of_interest_requestExpected success footer from the smoke example:
✅ mapkit OK
- The examples are designed to exit successfully on a headless macOS host.
- Some UI-heavy integration tests are
#[ignore]undercargo testbecause MapKit view/rendering objects require a dedicated main-thread process; the matching numbered examples exercise those APIs directly. MKUserTrackingButtonis not exposed as a standalone native macOS class in the SDK, so this crate wraps the equivalentMKMapView.showsUserTrackingButton/userTrackingModefunctionality instead.COVERAGE.mdandCOVERAGE_AUDIT.mddocument the 100% audited surface, the headless-safe modeling notes for UI/controller APIs, and the two exempt SDK declarations.
Licensed under either of Apache-2.0 or MIT at your option.