Skip to Content
PlatformsiOSTroubleshooting

Troubleshooting

initialize()’s completion resolves false, or crashes in debug

If neither setApiKey() nor the OneSygnalApiKey Info.plist entry resolves to a non-blank string, initialize() calls assertionFailure(...) before resolving the completion with false. In a debug build, assertionFailure traps — this looks like a crash, not a graceful failure. In a release build, assertions are compiled out, so you just get completion?(false) (or await initialize() returning false) with no crash. This asymmetry is a known, documented gap — Android’s equivalent path reports false in both configurations.

The trap message is:

OneSygnal API key not found. Add key "OneSygnalApiKey" with your API key to your app's Info.plist.

Fix: add the OneSygnalApiKey key to Info.plist, or call setApiKey() before initialize().

setApiKey() doesn’t seem to do anything

Two silent-no-op cases:

  • Blank string. setApiKey("") (or all-whitespace) is a no-op — it leaves any prior override, or the plist key, in place, rather than clearing it or throwing.
  • Called after initialize(). The key is read once, at initialize() time. Calling setApiKey() afterward has no effect until the next initialize() (e.g. after shutdown()).

isInitialized() returned true, but surveys never showed and track() calls fail

initialized is set true synchronously inside initialize(), before the background config/user/survey fetch (backgroundInit) has actually run or settled — so there’s a real window where isInitialized() reports true while setup is still in flight. If the fetched config’s status isn’t "active" or "trial" (a server-side kill switch), backgroundInit flips initialized back to false and resolves the original initialize() completion with false — but any code that already read isInitialized() as true during that window saw a stale answer. Prefer gating on the initialize() completion/await result or the ready event (see Events) rather than polling isInitialized().

A call I made returned false / did nothing

track() returns false (a genuine return value, not queued) if the SDK isn’t initialized yet, or if setSurveysEnabled(false) is in effect. identify(), logout(), reset(), and shutdown() all no-op (their completion still fires, with false for identify) if called before initialize() has completed — there is no call-queuing on iOS the way the web loader queues pre-ready calls. Call these only after initialize()’s completion (or ready) has fired.

Survey didn’t show even though a trigger should have matched

SurveyWindowOverlay.show() fails closed if there’s no foreground UIScene available at the moment of the attempt — the throttle state (setSurveyActive) is rolled back and nothing is shown, with no error surfaced. This can happen if the trigger fires while the app is backgrounded or between scene transitions. There is no retry — the next trigger match gets its own attempt.

Building/testing locally: swift test looks green but proves nothing

The whole public API (Api/OneSygnal.swift) is wrapped in #if canImport(UIKit). A plain swift test builds for native macOS, where UIKit doesn’t exist, so the API surface — and every test against it — silently compiles away. Use xcodebuild test -scheme OneSygnalSDK -destination 'platform=iOS Simulator,name=<device>,OS=latest' instead. An unavailable simulator device name makes xcodebuild exit 70 without running anything, which reads like a build failure rather than a missing simulator — check the device name first if that happens.

LocalOverride.swift pointed my build at the wrong host/key

Sources/OneSygnal/Api/LocalOverride.swift defines localApiHostOverride and localApiKeyOverride, both checked ahead of the plist/production values, for pointing a dev build at a local stack. It’s marked git update-index --skip-worktree, so a non-nil local value won’t show up in git status — and because the Flutter bridge vendors this SDK’s source directory wholesale, a local override here silently applies to Flutter iOS builds too. If native calls are hitting an unexpected host or key, check this file isn’t set to a non-nil value.