Skip to main content

Troubleshooting (iOS)

Work top-down. Start with the raw curl from Integration → Verifying the fetch — it tells you whether the problem is the server (auth / campaign) or the client (SDK config / device).


1. The fetch returns 401 {"message":"Invalid sdkKey"}

The key does not resolve to an active source in the environment you are hitting. Check, in order:

  1. Right keysdkKey (or the SDK apiKey it defaults to) is the public key for a real, active in-app source.
  2. Right environment — the source exists in the environment your fetchEndpoint targets (e.g. an EU key against api-eu, not a prod key against EU).
  3. Right URL — the URL includes the correct prefix. Most deployments need /engage in the path (…/engage/v1/push/inapp/fetch). A 404 or HTML response means the prefix/host is wrong.

Until the fetch stops returning 401, nothing can render on any device.


2. The fetch returns 201 but messages is empty

Auth is fine; no campaign matched. Re-check the Campaign Setup checklist. In practice the cause is almost always one of:

CauseFix
Campaign is not API-pull (delivery mode is push)Author it with delivery mode API pull (deliveryMode: "api").
Campaign is not LIVESet status to LIVE.
Campaign is action/trigger-basedPull only supports Everyone / Audience.
Audience campaign, user not a memberTest with Everyone first; ensure the user is identify()-ed and lives in the right environment.
condition.target is set but the fetch sent a different / no targetMatch the screen name, or clear the target.
Time window closeddisplayTime in the past, expireDate in the future.
Wrong project / environmentThe sdkKey resolves to a different project than the one that owns the campaign — see Environment matching.
Already delivered to this userEach campaign is delivered to a distinctId once. Test with a fresh distinctId (or reinstall).
Just published — list cacheThe active-campaign list can be cached briefly; wait up to a few minutes.

3. The fetch returns a message but nothing shows

SymptomCause / fix
Nothing renders, banner is blankThe campaign matched but has empty layout content. Author real content.
It showed once and never again1-hour per-pushId de-dup, and permanent per-user server de-dup. Use a fresh distinctId to re-test.
It renders on the wrong screenRendering uses the foreground screen at render time; check excludedActivities and your screen-targeting call.

Turn on debugLogging = true and watch the Xcode console for the fetch, the status code, de-dup skips, and render decisions.


4. iOS-specific gotchas

  • The automatic fetch fires on foreground and on viewDidAppear (screen change). In a pure SwiftUI app that stays under one host controller, navigation pushes and the initial appearance fire it, but plain TabView switches may not. Use a manual per-screen refreshEngageInAppMessages(target:) for reliable per-screen behavior — see Screen targeting.
  • If setup() runs after the app is already active (e.g. a post-login async bootstrap), the first foreground fetch may be missed until the next background→foreground cycle. Trigger a manual fetch after setup if needed.

5. Nothing happens at all (no request)

  • engageInAppConfig is nil → the feature is off. Set it before setup().
  • distinctId is empty → the fetch is skipped. Ensure the SDK has an anonymous or identified id.
  • autoFetchOnForeground = false and you never call refreshEngageInAppMessages(...) → there is no trigger. Either enable auto-fetch or add a manual call.