How Remote UI is selected
The app requests a placement with a locale and user ID. PNLight returns a config when the placement is enabled and a matching config is available. The dashboard tracks:- Requests: users who requested the placement.
- Shown: users who received a UI config that could be shown.
Render a placement
RemoteUiView calls getUIConfig internally. On the first app launch, when you use attribution from AppsFlyer, wait 4-5 seconds after AppsFlyer initialization before showing the placement so conversion data has time to arrive. When attributionRequired is true, the SDK also waits for attribution internally before requesting the config.
Handle actions
Remote UI actions are delivered to your app. Use action IDs, paths, or query parameters to decide what the app should do. Different placements can return different actions, so keep the handler explicit. Common actions:- Start a purchase.
- Return the user to the main app screen after a successful subscription.
- Close the screen.
- Open another app screen.
- Track a product interaction.
Fetch configs manually
UsegetUIConfig if you need to fetch the placement configuration yourself. On the first app launch, when attribution is required, call it after sending attribution and wait 4-5 seconds after AppsFlyer initialization before requesting the config. The SDK still waits for attribution internally when attributionRequired is true.
Config cache behavior
Remote UI configs are cache-first by default. If a cached config exists, the SDK can return it immediately and refresh it in the background with an ETag request. This keeps repeat displays responsive while still picking up dashboard changes. UseignoreCache when the app must wait for the latest server response, such as during QA or after the user changes a state that should affect targeting.
Handle missing configs and errors
Anull or empty config means PNLight did not return UI for that placement. This can happen when the placement is disabled, targeting does not match, show-once rules suppress the placement, capture protection blocks the user, or no matching locale config exists.
React Native and Flutter wrappers surface loading errors separately from missing UI. Use onError on RemoteUiView or handle getUIConfig errors when you fetch manually.
Swift apps that fetch manually can use getUIConfigResult to distinguish all outcomes: