Skip to content

Fix all build warnings (iOS 26 concurrency + deprecations)#61

Merged
kyleve merged 7 commits into
mainfrom
fix/build-warnings
Jul 6, 2026
Merged

Fix all build warnings (iOS 26 concurrency + deprecations)#61
kyleve merged 7 commits into
mainfrom
fix/build-warnings

Conversation

@kyleve

@kyleve kyleve commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

A clean build of both CI schemes (Stuff-iOS-Tests, Foreman-macOS-Tests) surfaced 10 warnings in our own code, all on iOS. This drives the whole repo to zero compiler/asset warnings, split into focused, bisectable commits.

One commit per concern:

  • Clear Where's unset AccentColor — clears ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME (Where tints per-region, ships no global accent color), matching the other app targets, silencing an asset-catalog warning.
  • RegionSummaryCard Canvas isolation — read the Sendable style.tint into a local before the nonisolated Canvas renderer closure.
  • LifecycleStep condition tests — the @MainActor (Sendable) condition closure tripped "mutated after capture"; read the flag through a reference.
  • WhereResetTests weak let — the weak binding is never reassigned (#WeakMutability).
  • LocationNamer → MapKitCLGeocoder/reverseGeocodeLocation are deprecated in iOS 26; migrate to MKReverseGeocodingRequest. PlaceComponents now derives its "City, Country" label from MKAddressRepresentations (cityName/regionName), and the geocode runs on the main actor (MapKit vends non-Sendable MKMapItems there).
  • Background-launch detectionUIApplication.LaunchOptionsKey.location is deprecated in iOS 26; derive the LifecycleReason from the launch-time UIApplication.State instead. The CLLocationManager installed in initializePrerequisites still delivers the buffered event.
  • Guard the location attribution — a background launch is attributed to .background(.location) only when the app is authorizedAlways (the prerequisite for the significant-change/visit wake Where registers for), and to .background(.other) otherwise, so a future non-location background cause isn't mislabeled. The cause is informational (both stay on the background step path), so behavior is unchanged today.

Behavior notes

  • Reverse-geocode labels: stay "City, Country" for the common case. iOS 26's MapKit dropped CLPlacemark's standalone administrative-area field (only preformatted strings + cityName/cityWithContext/regionName remain), so a city-less coordinate that previously fell back to "State, Country" now degrades to the country name. This is an SDK-level limitation, confined to remote coordinates.
  • Background-relaunch detection now keys off the launch-time application state (guarded by location authorization) rather than the launch-options dictionary. Where only wakes headless for Always-authorized location events, so the mapping is preserved.

Test plan

  • xcodebuild clean build-for-testing for Stuff-iOS-Tests — 0 code/asset warnings
  • xcodebuild clean build-for-testing for Foreman-macOS-Tests — 0 code warnings (only the pre-existing, benign appintentsmetadataprocessor "no AppIntents.framework" notes remain)
  • ./swiftformat --lint clean
  • Ran affected suites green: WhereAppTests (incl. the authorized/unauthorized background split), PlaceComponentsTests, WhereResetTests, LifecycleStepConfigurationTests
  • CI (Stuff-iOS-Tests + Foreman-macOS-Tests) green

kyleve and others added 7 commits July 5, 2026 22:40
The Where app tints per-region and ships no global accent color, but
(unlike RegionViewer and Foreman) never cleared
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME, so actool warned that
'AccentColor' wasn't present in any asset catalog.

Co-authored-by: Cursor <cursoragent@cursor.com>
The stamp-paper Canvas renderer runs nonisolated, so reading the
main-actor `style.tint` inside it warned. Read the Sendable Color into a
local before the closure and capture that instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
LifecycleStep.condition is a @mainactor (hence Sendable) closure, so
capturing a local `var flag` and flipping it afterward tripped Swift 6's
"mutated after capture by sendable closure". Read the flag through a
small MutableFlag reference instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
`weakOriginal` is never reassigned, so the WeakMutability warning wants a
`let`. Swift 6.2 allows `weak let`, so use it.

Co-authored-by: Cursor <cursoragent@cursor.com>
CLGeocoder and reverseGeocodeLocation are deprecated in iOS 26. Switch to
MKReverseGeocodingRequest. MapKit no longer exposes structured CLPlacemark
fields, so PlaceComponents now derives its compact "City, Country" label
from MKAddressRepresentations (cityName / regionName). The geocode runs on
the main actor because MapKit vends its non-Sendable MKMapItems there; only
the resulting String crosses back.

Behavior note: a city-less coordinate that previously fell back to
"State, Country" now degrades to the country name.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ation key

UIApplication.LaunchOptionsKey.location is deprecated in iOS 26. Derive the
LifecycleReason from the launch-time UIApplication.State instead: a
.background launch means iOS woke the process headless, which for Where only
happens to service a queued CoreLocation event. The CLLocationManager
installed in initializePrerequisites still delivers the buffered event.

WhereLaunch.lifecycleReason now maps UIApplication.State -> LifecycleReason
(covered by pure tests); the AppDelegate test asserts it wired the reason
from the live launch state. Also refresh the LifecycleKit README example.

Co-authored-by: Cursor <cursoragent@cursor.com>
lifecycleReason mapped every headless (.background) launch to
.background(.location), which over-claims: iOS only wakes Where for a
significant-change/visit event, and that requires Always authorization.
Guard the location attribution on CLAuthorizationStatus.authorizedAlways
and fall back to .background(.other) otherwise, so a future non-location
background cause isn't mislabeled. The cause is informational (both stay on
the background step path), so behavior is unchanged today.

Tests now cover the authorized/unauthorized background split, and the
AppDelegate smoke test asserts the deterministic foreground mapping.

Co-authored-by: Cursor <cursoragent@cursor.com>
@kyleve kyleve merged commit 9794ea3 into main Jul 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant