Configuration for the In App survey in the native ios.
Step 1: import xebompack_io
Step 2: Getting Your Credentials from the Xebo Platform.
All three values required for SDK configuartion are available directly in your Xebo Dashboard. No manual setup needed - just copy and paste.
API Key (api key)
Log in to your Xebo account at app.xebo.ai
Go to the right first name of your Id then click icon and options are available go to My Account in the account details → API Keys
Copy your API Key
The API key authenticates all SDK requests. Keep it private — do not commit it to public repositories.
Collector ID (collector id)
In the Xebo Platform open your Survey those want to show in a app survey.
Navigate to Collectors.
Select the SDK collector.
Copy the Collector ID from the collector page.
A Collector is a distribution channel linked to a specific survey. The SDK uses this ID to automatically find and load the correct survey.
Zone (zone)
az1-api.xebo.ai “az1“ (Zone to use)
az2-api.xebo.ai “az2“
az4-api.xebo.ai “az4“
If you are unsure of your zone, contact your account manager or check the API base URL shown in your dashboard settings.
Final Configuration
XeboNativeSurveyManager.shared.configure(
apiKey: "YOUR_API_KEY",
collectorId: "YOUR_COLLECTOR_ID",
zone: "az2"
)Call configure() once in AppDelegate.didFinishLaunchingWithOptions. The SDK immediately pre-fetches the survey in background so presentation is instant.
Trigger 1 — Action Completion (Instant)
Show the survey when a user completes an action.
@IBAction func purchaseCompletedTapped(_ sender: UIButton) {
XeboNativeSurveyManager.shared.fetchAndPresentSurvey(on: self)
}Trigger 2 — Time Delay
Show the survey after N seconds on screen.
class HomeViewController: UIViewController {
private var countdownTimer: Timer?
private var remainingSeconds = 15
override func viewDidLoad() {
super.viewDidLoad()
XeboNativeSurveyManager.shared.configure(
apiKey: "YOUR_API_KEY",
collectorId: "YOUR_COLLECTOR_ID",
zone: "az2"
)
countdownTimer = Timer.scheduledTimer(
timeInterval: 1.0, target: self,
selector: #selector(tick), userInfo: nil, repeats: true
)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
countdownTimer?.invalidate()
}
@objc private func tick() {
remainingSeconds -= 1
if remainingSeconds <= 0 {
countdownTimer?.invalidate()
XeboNativeSurveyManager.shared.fetchAndPresentSurvey(on: self)
}
}
}Trigger 3 — Visit Threshold (Nth Visit)
Show the survey on every Nth visit to a screen.
class ProductViewController: UIViewController {
private let visitKey = "visit_count"
private let requiredVisits = 3
override func viewDidLoad() {
super.viewDidLoad()
XeboNativeSurveyManager.shared.configure(
apiKey: "YOUR_API_KEY",
collectorId: "YOUR_COLLECTOR_ID",
zone: "az2"
)
checkVisitThreshold()
}
private func checkVisitThreshold() {
var count = UserDefaults.standard.integer(forKey: visitKey)
count += 1
UserDefaults.standard.set(count, forKey: visitKey)
if count >= requiredVisits {
UserDefaults.standard.set(0, forKey: visitKey)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
XeboNativeSurveyManager.shared.fetchAndPresentSurvey(on: self)
}
}
}
}Trigger 4 — Lowest Response Survey
Show the survey with the fewest responses from a set of surveys.
let surveyUUIDs = [
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
]
XeboNativeSurveyManager.shared.fetchAndPresentLowestResponseSurvey(
from: surveyUUIDs,
on: self
)Trigger 5 — Custom Attributes (Edata)
Attaches user identify and custom data to every survey response submitted by the SDK.Call it once after the user logs in. The data is stored internally and sent automaticallt wirh each survey sunmission.
Basic usage — standard fields only:
XeboNativeSurveyManager.shared.setUser(XeboUserData(
name: "Sheetal",
email: "sheetal@example.com",
phone: "+1234567890",
uniqueId: "user_123",
country: "US",
city: "New York"
))With eData — custom fields your app defines:
XeboNativeSurveyManager.shared.setUser(
XeboUserData(
name: "John Doe",
email: "john@example.com",
phone: "+91 9876543210",
uniqueId: "USR_001",
country: "India",
city: "Mumbai",
eData: [
"plan": "premium",
"account_id": "ACC_123",
"age_group": "25-34"
// any key-value pairs your business needs
]
)
)Clear on Logout
XeboNativeSurveyManager.shared.clearUser()
Theme Customization
Set Brand colour only
XeboNativeSurveyManager.shared.configureTheme(primaryColor: .systemIndigo)Full theme
XeboNativeSurveyManager.shared.configureTheme(
XeboAppTheme(
primaryColor: UIColor(red: 0.25, green: 0.18, blue: 0.82, alpha: 1),
backgroundColor: .white,
textColor: .black,
fontFamily: "Georgia",
cornerRadius: 16
)
)Dark Mode
XeboNativeSurveyManager.shared.configureTheme(
XeboAppTheme(
backgroundColor: UIColor(white: 0.1, alpha: 1),
textColor: .white
)
)Offline Queue
No extra code needed. The SDK handles it automatically:
Survey submitted with no internet → saved locally in
UserDefaultsNetwork returns → SDK auto-retries and submits all queued responses.
App relaunched with network → pending queue flushed on startup.
// Manually flush (optional)
XeboNativeSurveyManager.shared.flushQueue { success in
print(success ? "All sent" : "Some still pending")
}
// Check pending count (optional)
let pending = XeboNativeSurveyManager.shared.getQueuedResponses()
print("\(pending.count) response(s) queued")
// Clear queue (optional)
XeboNativeSurveyManager.shared.clearQueue()Supported Question Types
Type | Description |
|---|---|
Single Choice | One option from a list |
Multiple Choice | Multiple options from a list |
Dropdown | Single selection dropdown |
Single Text Box | Open-ended single line |
Multiple Text Box | Multiple open-ended fields |
NPS | Net Promoter Score (0–10) with optional follow-up |
Multi NPS | NPS grid for multiple items |
Rating | Star / Heart / Circle / Tile / Emoji |
Multi Rating | Rating grid for multiple items |
Thank You | Closing screen after submission |
Full AppDelegate Setup
import UIKit
import xebompack_io
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
XeboNativeSurveyManager.shared.configure(
apiKey: "YOUR_API_KEY",
collectorId: "YOUR_COLLECTOR_ID",
zone: "az2"
)
XeboNativeSurveyManager.shared.configureTheme(
XeboAppTheme(primaryColor: .systemIndigo, cornerRadius: 16)
)
return true
}
}API Reference
Method | Description |
|---|---|
| Initialize with collector ID |
| Initialize with direct survey ID |
| Show survey (uses cache if pre-fetched) |
| Show lowest-response survey |
| Apply full XeboAppTheme |
| Set accent color only |
| Retry all offline-queued responses |
| Returns pending offline responses |
| Clear all queued responses |
XeboAppTheme Properties
Property | Type | Description |
|---|---|---|
|
| Buttons, icons, selected states |
|
| Survey card background |
|
| Question text color |
|
| Custom font name |
|
| Survey card corner radius |
Zones
Zone | Environment |
|---|---|
| Production — az1 |
| Production — az2 |
| UAT (auto-detected from prefix) |
Troubleshooting
Issue | Fix |
|---|---|
Survey not showing | Check console for — verify API key & collector ID |
401 Unauthorized | Use a fresh API key from the Xebo dashboard |
App crashes on launch | Pod install with GitHub release tag. |
Offline queue not flushing | Queue auto-flushes when network returns — no action needed |
Console Logs
Filter by Xebo SDK in Xcode console:
>>> Xebo SDK: Survey pre-fetched (My Survey)
>>> Xebo SDK [Step 1/3] Fetch Collector — Status: 200
>>> Xebo SDK [Step 2/3] Fetch Survey — Status: 200
>>> Xebo SDK [Step 3/3] Submit Response — Status: 200
>>> Xebo SDK: Response saved to offline queue (total: 1)
>>> Xebo SDK: Flushing 1 offline response(s)...
>>> Xebo SDK: Flush done — 0 failed, 1 sent