fix: [SDK-4757] recover startup when initialized before UIApplicationMain#1677
Open
nan-li wants to merge 5 commits into
Open
fix: [SDK-4757] recover startup when initialized before UIApplicationMain#1677nan-li wants to merge 5 commits into
nan-li wants to merge 5 commits into
Conversation
Temporarily remove the demo's AppDelegate and call OneSignal.initialize from the SwiftUI App initializer, before UIApplicationMain runs. On a clean install this reproduces the 5.5.2 regression: no OSRequestCreateUser is ever sent, so no anonymous user or push subscription is created. Reverted at the end of this branch; kept in history for reference. Co-authored-by: Cursor <cursoragent@cursor.com>
…tionMain ComputeInitialStorageReadable read UIApplication.sharedApplication.isProtectedDataAvailable, which messages nil before UIApplicationMain has run (e.g. SwiftUI App.init()) and silently returns NO. On a fresh install the storage-readiness latch therefore seeded NO and every gated component (user manager, operation repo, session) no-opped. Because the device is never locked in this flow, UIApplicationProtectedDataDidBecomeAvailable never posts, so the SDK stayed gated forever and OSRequestCreateUser was never sent. Handle nil sharedApplication explicitly: a user-initiated launch implies the device is unlocked, so storage is readable. Only a prewarm-created process can reach this point while storage may still be locked, and iOS marks those with the ActivePrewarm environment variable, so defer only in that case. The variable is cleared after launch completes, but pre-UIApplicationMain always precedes that, so the read is reliable. Co-authored-by: Cursor <cursoragent@cursor.com>
When init defers because storage is not yet readable, recovery previously hinged solely on UIApplicationProtectedDataDidBecomeAvailable, which only posts on a lock-to-unlock transition. If storage was readable all along — a prewarm-created process the user later foregrounds, or a prior-session sentinel present while UserDefaults content was lost — the notification never posts and the deferral is permanent. Also observe didFinishLaunching and didBecomeActive: once UIApplicationMain has run, sharedApplication exists, so consult the real isProtectedDataAvailable and run the same once-only recovery (start user manager, resend push token, start Live Activities and IAM, new session). The live re-check keeps background launches before first unlock deferred until the unlock notification posts, as before. Co-authored-by: Cursor <cursoragent@cursor.com>
Undo the temporary SwiftUI App.init() repro setup now that the fix is in place; the demo initializes OneSignal from application(_:didFinishLaunchingWithOptions:) again, matching main. Co-authored-by: Cursor <cursoragent@cursor.com>
fadi-george
approved these changes
Jun 15, 2026
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.
Description
One Line Summary
Fix anonymous user creation when OneSignal initializes from SwiftUI
App.init()beforeUIApplicationMainexists.Details
Motivation
OneSignal iOS SDK 5.5.2 could permanently gate startup on clean installs when initialized from a pure SwiftUI
App.init(). In that lifecycle,UIApplication.sharedApplicationis nil beforeUIApplicationMain; the previous protected-data readiness check silently treated that asfalse, deferred the user manager/session startup, and could wait forever for a protected-data notification that never fires on an already-unlocked device. The result was no anonymous user or push subscription creation.Scope
This change is limited to SDK startup readiness around protected-data availability. It explicitly handles pre-
UIApplicationMaininitialization, distinguishes actual iOS prewarm usingActivePrewarm, and adds lifecycle-based recovery onceUIApplicationexists and reports protected data is available. It does not change public APIs.Other
The branch history intentionally includes a temporary demo repro commit followed by a restore commit, so reviewers can check out the repro state if needed. The net PR diff only changes
iOS_SDK/OneSignalSDK/Source/OneSignal.m.Testing
Unit testing
No new unit tests were added for the UIKit/SwiftUI launch-order path.
Manual testing
Manually verified on an iOS 26.5 iPhone 17 Pro simulator:
App.init(): before the fix,UIApplication.sharedApplicationwas nil, startup stayed gated, andOSRequestCreateUserdid not fire.ActivePrewarm=0was treated as readable,OSRequestCreateUserreturned 201, and anonesignal_idwas hydrated.onesignal_identity.jsonwhile removing UserDefaults-backed state, then relaunching and observing the lifecycle recovery path start deferred OneSignal components and sendOSRequestCreateUser.Affected code checklist
Checklist
Overview
Testing
Final pass
Made with Cursor