Swift 6 strict-concurrency fixes and Dart-owned annotation image pixel ratio - #17
Merged
Merged
Conversation
Xcode 26's Swift-6 language mode rejected patterns the older CI toolchain accepted: - registrar hand-off into MainActor.assumeIsolated during plugin registration, marked nonisolated(unsafe) — registration never leaves the main thread, it just isn't Sendable-provable - FlutterMapView's CLLocationManagerDelegate conformance, now @preconcurrency — callbacks arrive on the thread that created the manager, which is main - MKPolyline.contains/meters touching MKMapView geometry from a nonisolated extension, now @mainactor since the sole caller TouchHandler already is Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces native UIScreen.main/NSScreen.main scale lookup (PlatformScreen, deleted) with a Dart-supplied imagePixelRatio on the icon wire format — Flutter owns device pixel ratio, matching how first-party map plugins pass bitmap scale. - MKAnnotationIcon.image gains optional imagePixelRatio, defaulting to the implicit view's devicePixelRatio - MKAnnotationIcon.asset passes the resolved asset variant's key.scale, so a 2x asset on a 3x device decodes at its true ratio (previously always screen scale) - Snapshot scale now reads the map view's traitCollection.displayScale instead of UIScreen.main - pigeon bumped 27.1.0 -> 27.3.0; regenerated messages.g.swift re-applies the O(N) deepEquals dictionary patch and marks FlutterApi completions @sendable (both now documented in the schema header) - darwin copy of messages.g.swift synced with ios (drifted since 0.3.4) - new unit tests cover serialization, defaulting, equality of the ratio Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Strict local Xcode 26 (Swift 6 language mode) couldn't build the plugin at all — the first blocker was
MainActor-isolatedUIScreen.maininside the nonisolatedPlatformScreen.scale. Peeling that back surfaced a chain of strict-concurrency errors (delegate conformances, registrar Sendability,MKMapView-touching polyline helpers, pigeon-generated completion captures), and the correct fix for the original blocker turned out to be a real API improvement rather than a workaround: Dart now owns the pixel ratio for annotation images instead of reading it off the platform screen.Changes
Swift 6 strict-concurrency fixes (minimal, each annotated with a comment stating the main-thread guarantee it encodes):
CLLocationManagerDelegateonFlutterMapView@preconcurrencyconformanceFlutterPlatformViewonMapKitViewHost@preconcurrencyconformanceMapKitPlugin.swift)nonisolated(unsafe)MKPolyline.contains/.metersextension helpers@MainActorDart-owned image pixel ratio (the Flutterish replacement for the deprecated
UIScreen.mainlookup):imagePixelRatiofield on the icon wire format (pigeons/messages.dart,messages.g.dart).MKAnnotationIcon.image(png, {imagePixelRatio})defaults to the implicit view'sdevicePixelRatiowhen omitted.MKAnnotationIcon.assetnow passes the resolved variant'skey.scaleasimagePixelRatio— this is a real behavior fix, not just plumbing: a 2x asset selected on a 3x device was previously decoded at the wrong ratio.mapView.traitCollection.displayScaleinstead of the deletedPlatformScreen.27.1.0→27.3.0. Regenerating now requires manual re-application of three things tomessages.g.swift, documented in thepigeons/messages.dartheader: the O(N)deepEqualsdictionary-lookup branch (stock pigeon emits O(N·M) and silently reverts the 0.3.4 perf fix),@SendableonMapKitFlutterApicompletions (Xcode 26+ rejects a plain completion captured in the channel reply closure), and copying the result overdarwin/mapkit_flutter/'s checked-in copy.darwinandioscopies ofmessages.g.swifthad silently diverged since 0.3.4.Test plan
flutter analyzeclean (package and example)Notes
Marker icons and default-path image icons are unchanged on 1x/2x/3x-matched setups. The only visible behavior change is correct sizing when an asset variant's scale doesn't match the screen's scale, and macOS image sizing now uses the Dart-supplied ratio instead of
NSScreen.main.🤖 Generated with Claude Code