mapkit_flutter 0.5.1
mapkit_flutter: ^0.5.1 copied to clipboard
MapKit for Flutter — MKMapView on iOS and macOS with Apple's exact symbol names: annotations, clustering, overlays, tile overlays, Look Around, snapshots, mockable controller.
Changelog #
0.5.1 - 2026-10-16 #
Fixed #
- README: tile overlays take only
alpha, not stroke or fill styling;openLookAroundreturns abool; on macOS it throws aMapKitPlatformExceptionwith codeunsupported-platform, not aMapKitUnsupportedPlatformException.
Changed #
- The README opens with what the package does, why to use it and a short example. Every Dart sample in the README and the agent skill is analyzed with the package's lints and fits pub.dev without scrolling sideways.
- Regenerated the platform channel code with Pigeon 29.0.10 (header only).
0.5.0 - 2026-10-15 #
Misuse now fails loudly in every build mode instead of being clamped, ignored or degraded, and the controller reports outcomes instead of swallowing them.
Breaking #
- Value types validate in all build modes and lost their
constconstructors.CLLocationCoordinate2D,MKCoordinateSpan,MKCameraZoomRange,MKMapCamera,MKPointAnnotation,MKPolyline,MKPolygon,MKCircleandMKTileOverlaythrow anArgumentErrorfor non-finite numbers, out-of-range spans/alpha/zoom levels, negative widths or radii, and a zoom range whose minimum exceeds its maximum — release builds no longer pass them through to MapKit. Migration: dropconstfrom these constructor calls;MKMapView(cameraZoomRange:)defaults to the newMKCameraZoomRange.unboundedconstant. CLLocationCoordinate2Drejects a latitude outside[-90, 90]instead of clamping it (swapped arguments used to land on a pole). Longitude still wraps into[-180, 180).MKPolylinerejects a singlegradientColorsentry (it used to drawstrokeColorsilently); pass none or at least two.MKPolylinerejects alineDashPatternwith a negative or non-finite length, or with only zeros (CoreGraphics drew such a line as nothing). Dotted patterns like[0, 15]stay valid.- Duplicate ids within one of
MKMapView's sets throw anArgumentErrorin all build modes (release builds used to keep only the last object). - Tap capture is explicit: overlays send
consumeTapEventsas given (onTapno longer implies it) andonTapwithoutconsumeTapEvents: truethrows.MKPointAnnotationgainscalloutConsumesTapEvents(defaultfalse), andonCalloutTaprequires it. Equality no longer tracks callback presence. Migration: addconsumeTapEvents: truenext to an overlay'sonTap, andcalloutConsumesTapEvents: truenext toonCalloutTap. MKPointAnnotation.onTapis removed — it wasmapView(_:didSelect:)minus programmatic selections. UseonSelect, which fires for a user tap and forselectAnnotation.MKPointAnnotation.onDragis removed — MapKit reports drag-state changes, not movement, so it fired once per drag with the coordinate where the drag began, never while the pin moved. UseonDragStartfor the start andonDragEndfor the dropped coordinate.MKMapViewController.showCallout/hideCallout/isCalloutShownare renamed to MapKit'sselectAnnotation/deselectAnnotation/isAnnotationSelected.selectAnnotationanddeselectAnnotationreturnFuture<bool>:falsewhen the id isn't on the map (and, forselectAnnotation, when the annotation is hidden) instead of silently doing nothing.MKMapViewController.cameraandregionreturnnullbefore the view's first layout (they returned a zero region and a camera with distance 0).CameraConvenienceshelpers throw aStateErrorthen,scrollByincluded (it was a silent no-op), andfitCoordinates([])throws anArgumentError(it was a no-op), as do a negativepadding/minimumSpan.openLookAroundreturnsfalseonly when no scene exists. A failed scene request or a missing presenter throwsMapKitPlatformException(look-around-failed), and macOS throwsunsupported-platform(it returnedfalsefor all of these).addTileOverlaywith an id already on the map throwsMapKitPlatformException(duplicate-id) instead of replacing it;removeTileOverlayreturnsFuture<bool>(falsefor an id that isn't on the map).- iOS-only settings on macOS throw a
MapKitUnsupportedPlatformExceptionnaming the setting (newfeaturefield):userTrackingMode: followWithHeading(it fell back tofollow),selectableMapFeatures,onMapFeatureSelected,insetsLayoutMarginsFromSafeArea: falseand an annotation'scalloutConsumesTapEvents(all silently ignored). showsUserLocation: trueno longer prompts for location permission (neitherMKMapViewnor google_maps_flutter does). Request when-in-use authorization in your app; without itonDidFailToLocateUserreports the failure.- Annotation image bytes that don't decode and unknown SF Symbol names fail the
update with
MapKitPlatformException(invalid-icon) instead of an invisible annotation or a plain marker. An invalid icon fails the whole update; nothing is half-applied. - A point-of-interest filter naming a category newer than the running OS (the
iOS 18 / macOS 15 values) fails with
MapKitPlatformException(unavailable-poi-category) instead of being dropped —including([.castle])on iOS 17 used to hide every POI. - MapKit rejecting a zoom range or camera boundary throws
MapKitPlatformException(invalid-argument) instead of silently leaving the map unbounded. MKMapSnapshotOptions.showsBuildingsis removed; it had no effect.
Added #
MKMapView.onUserTrackingModeChangedreports MapKit's own tracking-mode changes (mapView(_:didChange:animated:), e.g. dropping tononewhen the user pans), so the declareduserTrackingModecan stay in sync.- Image-icon
anchorPointworks on macOS (viacenterOffset); it used to be ignored there. - macOS snapshots draw annotations and overlays when
showsAnnotations/showsOverlaysare on, as iOS does; they used to contain only the base map although both options default totrue. - Snapshots draw annotations above overlays, matching the live map (overlays used to cover annotations on both platforms).
Changed #
MKMapViewimportspackage:flutter/widgets.dartinstead ofpackage:flutter/material.dart.MKStandardMapConfiguration.toString()andMKHybridMapConfiguration.toString()includepointOfInterestFilter;MKPointOfInterestFiltersubclasses overridetoString().- Polyline tap targets cover the visible stroke: half the
lineWidth, at least 8 points (it was a fixed 8 points). - A tap or click on an annotation view selects the annotation without also
firing the map's
onTap. - macOS: a click fires
onTaponce the double-click interval passes, and a double-click (which zooms) fires none, matching iOS taps (every click of a double-click used to fireonTap).
Fixed #
- Cross-type overlay ID collisions in
MapKitViewHostso polylines, polygons, and circles have independent ID namespaces. MKAnnotationIcon.assetslicesByteDataviews viaUint8List.sublistViewand loads from the resolvedAssetBundleKey.bundle.CLLocationCoordinate2Dwraps-180.00000000000003to-180.0instead of180.0.- Native
AnnotationController: gateonCalloutTappedoncalloutConsumesTapEvents, suppress spurious selection callbacks during icon-type swap of a selected annotation, updateMKMarkerAnnotationViewcallouts in place, and register cluster reuse identifier once onFlutterMapViewinit. - Native
takeSnapshot: guard against zero-size map view, project using the snapshot's camera/region options, honor custom annotation imagealphaon iOS, and render interior polygon holes withevenOddfill rule. openLookAroundwalks the fullpresentedViewControllerchain before presenting, waits out a running transition (UIKit postponed the presentation, so the future failed and Look Around appeared anyway), and throwsMapKitPlatformException(look-around-failed) when UIKit rejects the presentation; its future used to never complete.- A camera move made before the first layout (
setCamera/setRegion/setCenter, e.g. fromonMapCreated) is no longer overridden byinitialCamerawhen the view gets its size, including a move that lands between the resize and the layout pass. - Snapshots draw a polyline's
gradientColorsalong its length, including the tips of sharp miter joins; they used to draw the plainstrokeColor.
0.4.0 - 2026-10-04 #
Breaking #
- MKPointOfInterestCategory gained 33 values — exhaustive switches over it must handle them.
copyWith(x: null)now clears a nullable field instead of keeping it, so code that passes a possibly-null variable changes behaviour. Parameter types are unchanged from 0.3.7; omitting the argument still keeps the field.- The agent skill moved to skills/mapkit-flutter-scaffold/ (dart run skills@ get requires the package-name prefix).
Added #
- MKPointAnnotation.onSelect / onDeselect.
- MKMapView.onMapFeatureSelected (iOS) with MKMapFeature / MKMapFeatureType.
- 33 iOS 18 / macOS 15 MKPointOfInterestCategory values (ignored by filters on older OS versions).
- Apple privacy manifest (PrivacyInfo.xcprivacy) for SPM and CocoaPods.
Changed #
- Requires Dart 3.13 / Flutter 3.47 (was Dart 3.10 / Flutter 3.41).
- Platform channel regenerated with Pigeon 29; host→Dart events use its async Swift API.
- An overlay with onTap now consumes taps (onTap implies consumeTapEvents).
- fitCoordinates gains padding and minimumSpan; a single coordinate now frames 0.005° instead of zooming fully in.
- Only the top-most visible consuming overlay receives a tap (was every overlay under the point).
userTrackingModeis re-applied only when it changes, so unrelated rebuilds no longer snap a panned map back to tracking.showsUserTrackingButtonworks on macOS.- MKMapSnapshotOptions.showsBuildings has no effect (MapKit dropped it).
- onCameraMove fires continuously (gestures, momentum, animations) on iOS and macOS via mapViewDidChangeVisibleRegion.
- Docs: Look Around and showsUserTrackingButton platform notes corrected; per-platform differences table; deployment-target setup.
Fixed #
- Package.swift declares the FlutterFramework dependency (silences the Flutter 3.47 build warning).
- Unmounting a map now releases its native MKMapView, host and location manager (channel handlers were never removed).
- Geodesic polylines no longer corrupt memory on iOS/macOS 27 (MKGeodesicPolyline is no longer subclassed).
- A rebuild that lands before the platform view finishes creating no longer leaves taps on stale callbacks.
- In-range longitudes are stored verbatim (normalisation used to perturb them, e.g. 10.1 → 10.099999999999994).
initializesends one object per id, last wins, like the rebuild diff; duplicate ids now assert in debug.- Toggling
onCalloutTapon an existing annotation now reaches native. - The first annotation update after a drag is no longer dropped (Dart stays the source of truth: a drag the app ignores snaps back on the next changed rebuild).
MKPointOfInterestCategory.evChargerworks on iOS 17 (anincludingfilter with it no longer hides every POI).- Custom-image annotation callouts are no longer offset sideways.
onCalloutTapfires once per tap after reselecting an annotation (iOS).- Hidden overlays never take taps.
- Re-adding a tile overlay with the same id (including the empty id) replaces it.
- Snapshots now match the on-screen map: style (hybrid/imagery/muted/traffic/elevation/POI filter), rotated/pitched camera and dark mode.
- Snapshot polygon outlines start without a zero-length edge and draw the closing edge once (visible with dash patterns and translucent strokes).
- The podspec no longer forces -warnings-as-errors on CocoaPods consumers.
Removed #
- The hand-patched pigeon deepEquals dictionary branch (dead code — the schema has no Map fields) and the unused ios/ copy of the generated Swift file.
0.3.7 #
- Fix: iOS snapshot polylines now stroke as a single subpath, so
lineJoinapplies and dash patterns run continuously across vertices. A single-coordinate polyline now draws nothing instead of a round-cap dot, matching the live renderer. - Performance: iOS snapshots skip annotations whose drawn frame lies entirely outside the image; partially visible edge annotations still draw.
- Fix: podspec version now tracks pubspec — CocoaPods had advertised 0.3.0 since v0.3.1. CI guards against drift (and fails closed if no podspec matches).
- CI: macOS example build job added alongside iOS; integration workflow bounds
every
flutter testinvocation and recycles a wedged simulator between retries.
0.3.6 #
- Testing:
MKMapViewControlleris now an interface (abstract interface class) instead of afinal class, so code that drives a map can be mocked or faked in unit tests. The widget-only mutations (initialize,update*) moved to the internalMKMapViewControllerImpl, keeping the mockable surface to the public API.
0.3.5 #
- Fix: Marker annotation views dequeue with a safe cast and fallback instead of a forced downcast, hardening against a potential native crash.
- Performance: Hoisted the repeated
points()accessor out of the polyline hit-testing loop.
0.3.4 #
- Performance: Refactored Pigeon deep equality checks for maps to O(N), speeding up Flutter configuration passes.
- Performance: Overhauled overlay updates to use a true O(1) class-level
tracking dictionary (
overlaysById), eliminating O(N) localized allocation overheads and massively improving performance when animating individual overlays in large collections. - Fix: Addressed a Swift "ghost overlay" logic flaw where overlays being
simultaneously removed and updated could fall out of sync with the underlying
MKMapView.
0.3.3 #
- Fix: Per-object tap callbacks (annotation/polyline/polygon/circle) refresh on callback-only rebuilds.
- Fix: Toggling
onCalloutTappropagates to the native callout. - Fix: Guard polyline tap hit-testing against an empty coordinate list.
0.3.2 #
- Docs: Updated scaffolder skill (
skills/mapkit-flutter-scaffold/SKILL.md) to document overlay tap interactions and macOS snapshot limitations.
0.3.1 #
- Performance: Refactored annotation dequeuing to use generic reuse identifiers, enabling proper MapKit view recycling.
- Fix: Preserved selection state (callouts) when swapping marker/image types in-place.
- Fix: Repaired overlay tap containment tests for circles and polygons which were failing on unrendered local paths.
- Build: Added strict compiler flags (
-warnings-as-errors,-strict-concurrency=complete) and resolved iOS/macOS platform optionality discrepancies. - Docs: Correct lingering iOS-only references to iOS + macOS; add
macostopic.
0.3.0 #
- Added macOS support (Look Around stays iOS-only).
- Annotations now restyle correctly on in-place update and view reuse, including marker ↔ custom-image swaps.
0.2.1 #
- Silenced iOS build warnings for cleaner integration.
0.2.0 #
- Added Swift Package Manager support.
0.1.1 #
- Corrected supported platforms.
0.1.0 #
Initial release.