Skip to main content

Integration (iOS)

Enabling API-pull in-app messaging is a single config object on top of your normal SDK setup. When it is nil (the default), the SDK never issues a fetch, so the feature is off until you opt in. Set the config before PaylisherSDK.shared.setup(...).

import Paylisher

let config = PaylisherConfig(
apiKey: "phc_your_public_sdk_key",
host: "https://your-datastudio-host"
)
// …your other config…

let engageConfig = PaylisherEngageInAppConfig(
// Engage usually lives on a different host/prefix than analytics ingestion,
// so set the full URL explicitly (note the `/engage` prefix in most deployments):
fetchEndpoint: "https://api-eu.paylisher.com/engage/v1/push/inapp/fetch"
)
engageConfig.autoFetchOnForeground = true // default
engageConfig.maxMessages = 5
engageConfig.debugLogging = true // turn on while integrating
config.engageInAppConfig = engageConfig

PaylisherSDK.shared.setup(config)

Manual fetch (see Scenarios):

PaylisherSDK.shared.refreshEngageInAppMessages(target: "wallet")
// or, with no screen target:
PaylisherSDK.shared.refreshEngageInAppMessages()

Config reference — PaylisherEngageInAppConfig

Every field is optional. Identity fields are resolved by the SDK / Engage; you normally set only fetchEndpoint (when Engage is on a different host) and the tuning flags.

FieldTypeDefaultPurpose
fetchEndpointString?nil{host}/v1/push/inapp/fetchFull absolute URL of the fetch endpoint. Set this when Engage is not on your analytics host (the common case). The ack endpoint is derived as the sibling …/ack.
sdkKeyString?nil → SDK apiKeyThe public key Engage uses to resolve your project/source. Override only if the in-app source differs from analytics.
teamId / projectId / sourceIdString?nilOptional explicit identity. Normally omitted — Engage reverse-resolves them from sdkKey.
autoFetchOnForegroundBooltrueWhen true, the SDK fetches automatically on foreground and on screen change. When false, the SDK never fetches on its own — you drive it with refreshEngageInAppMessages(...).
maxMessagesInt1How many messages a single fetch may return (clamped to 1...5).
debugLoggingBoolfalseVerbose SDK logs for the fetch / render / ack path.
excludedActivities[String]["Splash"]View-controller class-name fragments where a message must not render. Messages are queued and shown on the next non-excluded screen.
excludedActivities and SwiftUI

excludedActivities matches the top view controller class name. It works for UIKit apps. In a pure SwiftUI app every screen lives under one host controller, so class-name matching cannot tell screens apart — gate screens with the manual, per-screen approach in Scenarios → Don't show on login/splash instead.


Verifying the fetch without a device

Exercise the exact request the SDK makes with curl. Use a fresh distinctId each time (delivered messages are de-duplicated per user):

curl -i -X POST "https://api-eu.paylisher.com/engage/v1/push/inapp/fetch" \
-H "Content-Type: application/json" \
-H "X-SDK-Key: phc_your_public_sdk_key" \
-d '{"distinctId":"probe-1","sdkKey":"phc_your_public_sdk_key","platform":"ios","maxMessages":5}'
  • 201 {"messages":[]} → auth is fine, but no campaign matched → see Campaign Setup.
  • 201 {"messages":[{…}]} → the server path works end-to-end → test on device.
  • 401 {"message":"Invalid sdkKey"} → the key does not resolve in this environment → see Troubleshooting.