Skip to content

Fix SIGABRT crash from background-location Info.plist misconfiguration#4

Merged
billdmar merged 1 commit into
mainfrom
fix/background-location-crash
Jun 10, 2026
Merged

Fix SIGABRT crash from background-location Info.plist misconfiguration#4
billdmar merged 1 commit into
mainfrom
fix/background-location-crash

Conversation

@billdmar

Copy link
Copy Markdown
Owner

The crash

The app aborted on launch with SIGABRT once "Always" location authorization had been granted (e.g. after testing the location prompt once). Crash report pinpointed it:

EXC_CRASH (SIGABRT) — CoreLocation NSException
  LocationManager.enableBackgroundUpdatesIfPermitted()  SafetyWatcherView.swift
  LocationManager.startTracking()
  SafetyWatcherView.body  (first layout)

Root cause

LocationManager sets allowsBackgroundLocationUpdates = true, but the built Info.plist was missing UIBackgroundModes = location. CoreLocation throws (→ abort()) when that property is set without the background mode declared.

Why it was missing: the project uses GENERATE_INFOPLIST_FILE = YES and declared INFOPLIST_KEY_UIBackgroundModes = location, but UIBackgroundModes is not one of the INFOPLIST_KEY_* names Xcode synthesizes into the generated plist — so it was silently dropped. (The location usage strings are synthesized keys, so those made it through, which is why the prompt appeared but the app then crashed.) This is pre-existing code from the background-location feature (#2) that had been compile-verified but never actually run.

Fix (two layers)

  1. Make the feature work — add BuildConfig/Info.plist declaring UIBackgroundModes=[location] and point INFOPLIST_FILE at it (both Debug/Release). GENERATE_INFOPLIST_FILE=YES stays on and merges this file on top. It's kept outside the Party Watcher/ synchronized source folder on purpose — a plist inside it gets auto-added to Copy Bundle Resources and used as INFOPLIST_FILE, which produces a "Multiple commands produce Info.plist" build error.
  2. Never crash again — harden enableBackgroundUpdatesIfPermitted() to only enable background updates if Bundle.main's UIBackgroundModes actually contains "location". Any future plist regression now degrades to foreground-only tracking instead of aborting.

Verification

  • xcodebuild buildBUILD SUCCEEDED; built Info.plist now contains UIBackgroundModes = [location] (verified with PlistBuddy), usage strings retained.
  • Installed on the Simulator, granted location-always (the exact condition that crashed before), launched → stays running, no new crash reports.
  • Set a location → live map renders, chat/quick-actions/contacts all functional.

Investigation

Root cause and fix were confirmed by three parallel read-only investigators (crash-report analysis, plist-synthesis research, and a broader crash-risk audit) before any code changed.

The app aborted on launch (SIGABRT) once 'Always' location authorization
was granted. Root cause: LocationManager set
`allowsBackgroundLocationUpdates = true`, but the built Info.plist was
missing `UIBackgroundModes = location`. CoreLocation throws an exception
when that setter runs without the background mode declared.

Why the plist was missing it: the project uses GENERATE_INFOPLIST_FILE=YES
and declared `INFOPLIST_KEY_UIBackgroundModes = location`, but
UIBackgroundModes is NOT one of the INFOPLIST_KEY_* names Xcode synthesizes
into the generated plist, so it was silently dropped (the usage strings,
which ARE synthesized keys, made it through). This is pre-existing code
from the background-location feature (#2) that had only been
compile-verified, never run.

Fix (two layers):
- Add BuildConfig/Info.plist declaring UIBackgroundModes=[location] and
  point INFOPLIST_FILE at it in both Debug/Release. Kept outside the
  'Party Watcher/' synchronized folder so it isn't also copied as a
  bundle resource (which would cause 'Multiple commands produce Info.plist').
  GENERATE_INFOPLIST_FILE stays YES and merges this on top.
- Harden enableBackgroundUpdatesIfPermitted(): only enable background
  updates if Bundle.main's UIBackgroundModes actually contains 'location',
  so any future plist regression degrades to foreground-only instead of
  crashing.

Verified: built plist now contains UIBackgroundModes=[location] (usage
strings retained); app launches and stays running in the Simulator with
always-location granted (the exact condition that crashed before); no new
crash reports.
@billdmar
billdmar merged commit 392d7b3 into main Jun 10, 2026
1 check passed
@billdmar
billdmar deleted the fix/background-location-crash branch June 10, 2026 23:46
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