I. The Dream: Silent Guardian

Every developer using location or time-sensitive data dreams of it: the app that works smartly in the background. For my earthquake alert app, iQuake, the goal seemed straightforward: use SwiftUI's modern tools to periodically check USGS (USA/Global) and TMD (Thailand) feeds in the background. When a significant quake happened near the user, pop up a helpful local notification. Simple, right? I reached for the shiny new .backgroundTask() modifier and BGAppRefreshTaskRequest, expecting a relatively smooth integration. Oh, how optimistic I was.

II. Laying the Foundation: Data Wrangling

III. The First Wall: The Sound of Silence

The background task handler simply refused to run. Not a peep in logs. Simulate Background Fetch? Nothing. Device idle and plugged in? Still nothing. Cue the epic debugging montage: Info.plist entries scrutinized. App reinstallations. Simulator resets. Desperation setting in.

IV. Plot Twist: Crashes, dasd, and the AppDelegate Detour

Then it crashed – hard. SIGABRT via NSAssertionHandler deep inside BGTaskScheduler. Even with .backgroundTask commented out! Enter the AppDelegate fix:

Crashes? Gone. Success? Not quite. dasd logs showed the task was submitted... but not allowed to run. "DecisionToRun:0." So close, yet so far.

V. Light at the End of the Tunnel (and an iPad Blind Spot)

Breakthrough! Using LLDB: e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@...] forced execution of the handler. It worked! Then, discovered iPad notifications weren't appearing due to missing authorization code. Added: UNUserNotificationCenter.current().requestAuthorization(...) in launch. Notifications: unlocked.

And finally, after weeks of debugging... a plugged-in, idle iPhone triggered a real notification from the background task. Victory.

VI. Lessons Learned (The Hard Way)

This was a wild debugging ride — one that tested patience, persistence, and plenty of coffee. Hope this saves someone else from the same fate.

Droid Crypt logo