A complete testing framework that validates your Iterable Swift SDK integration locally on your Mac before deploying to production.
This testing framework helps you verify that your iOS app correctly integrates with Iterable's marketing platform by testing:
- Push Notifications - Messages sent to your app users' devices
- In-App Messages - Pop-up messages shown within your app
- Embedded Messages - Content embedded in your app's interface
- Deep Links - Links that open specific screens in your app
Before you start, make sure you have:
- A Mac computer (macOS 13.0 or later)
- Xcode installed from the App Store
- An active Iterable account
- Basic familiarity with Terminal/Command Line
- Go to Iterable.com and log into your account
- In Settings, click on Project Settings
- Your Project ID is shown at the top
- Copy this ID for later use
IMPORTANT: You need BOTH types of API keys for complete integration testing:
Use for: Creating test users, managing data, sending campaigns
- Allows "Read and write Iterable data from a server-side application"
- Required: This setup script uses it to create your test user automatically
Use for: Actual Swift SDK integration testing
- Allows "Update users, track events and trigger messages from Iterable's mobile SDKs"
- Required: Your iOS app uses this for all SDK operations
-
In the Iterable dashboard, click on Integrations tab
-
Select API Keys from the drop down menu (You can click here to go there directly)
-
Click "Create New API Key"
-
Create TWO keys:
- One with "Server-side" type (for user management)
- One with "Mobile" type (for SDK testing)
- Important - While creating the mobile key do not select JWT Authentication checkbox.
-
Name them clearly like "Integration Tests - Server" and "Integration Tests - Mobile"
📝 Note: Both API keys look like this:
sk_1a2b3c4d5e6f7g8h9i0j
- Press
Cmd + Spaceto open Spotlight - Type "Terminal" and press Enter
- A black window will open - this is your Terminal
Copy and paste this command into Terminal and press Enter:
cd /Users/$(whoami)/Projects/swift-sdk/tests/business-critical-integrationCopy and paste this command and press Enter:
./scripts/setup-local-environment.shThe script will guide you through:
- ✅ Checking if your Mac is ready for testing
- ✅ Setting up an iOS Simulator
- ✅ Configuring your API keys
- ✅ Creating test configuration files
The script will ask for three things IN THIS ORDER:
- 📋 Project ID: Enter your Iterable Project ID from Step 1.4
- 🔑 Server-side API Key: Paste your server-side key for user management
- 📱 Mobile API Key: Paste your mobile key for SDK testing
The script will then automatically:
- ✅ Create a daily test user (e.g.,
2025-01-07-integration-test-user@test.com) in your project - ✅ Set up your local testing environment
- ✅ Configure everything needed for testing
Run this command to test push notification functionality:
./scripts/run-tests.sh pushYou should see output like:
🧪 Iterable Swift SDK - Local Integration Tests
✅ Configuration validated
✅ iOS Simulator ready
📱 Running push notification tests...
To test everything at once:
./scripts/run-tests.sh allFor more detailed information during testing:
./scripts/run-tests.sh all --verbose- In Finder, navigate to:
swift-sdk/sample-apps/swift-sample-app/ - Double-click
swift-sample-app.xcodeprojto open it in Xcode
- In Xcode, find the file
AppDelegate.swift - Look for the line:
let iterableApiKey = "" - Replace the empty quotes with your API key:
let iterableApiKey = "your_api_key_here"
- In Xcode, click the Run button (
▶️ ) - The app will open in the iOS Simulator
- Look for a yellow banner that says "🧪 INTEGRATION TEST MODE 🧪"
- You'll see test buttons at the bottom of the screen
- Test Push Registration: Checks if push notifications work
- Test In-App Message: Shows how in-app messages appear
- Test Deep Link: Validates link handling
- View Test Results: Shows a summary of test results
✅ Green checkmarks mean tests passed
❌ Red X marks mean tests failed
After running tests, check these folders:
reports/- Detailed test results in JSON and HTML formatlogs/- Technical logs for troubleshootingscreenshots/- Screenshots of test execution
- "Device token registered" - Push notifications are working
- "In-app message displayed" - Message system is functioning
- "Deep link processed" - Link handling is correct
Solution: Re-run the setup script and make sure you entered your API key correctly
Solution:
- Open Xcode
- Go to Window > Devices and Simulators
- Make sure you have at least one iOS simulator installed
Solution: Run this command to fix permissions:
chmod +x ./scripts/setup-local-environment.sh
chmod +x ./scripts/run-tests.shSolution: This is normal! Some tests may show warnings in a local environment that wouldn't occur with real users.
You can modify test settings by editing:
config/test-config.jsonCommon settings to adjust:
timeout: How long to wait for tests (in seconds)enableDebugLogging: Show more detailed outputtestUserEmail: Change the test email address
# Test only push notifications
./scripts/run-tests.sh push
# Test only in-app messages
./scripts/run-tests.sh inapp
# Test only embedded messages
./scripts/run-tests.sh embedded
# Test only deep linking
./scripts/run-tests.sh deeplinkTo see everything that's happening:
./scripts/run-tests.sh all --verbose --no-cleanup./scripts/setup-local-environment.sh --check./scripts/run-tests.sh --help| Command | What It Does |
|---|---|
./scripts/setup-local-environment.sh |
Initial setup |
./scripts/run-tests.sh all |
Run all tests |
./scripts/run-tests.sh push --verbose |
Test push with details |
open reports/ |
View test reports in Finder |
The JWT Auth Retry screen (inside the integration tester app) exercises the SDK's unified JWT retry logic. Its response-mode radios determine where traffic actually goes — matching the Android network-tester's behavior:
| Mode | Destination | Notes |
|---|---|---|
Normal |
Real https://api.iterable.com |
Proxied with the SDK's real JWT. Use this to validate retry against prod-shape responses. |
401 |
Real https://api.iterable.com |
Proxied with the Authorization header swapped to an expired JWT. Real backend returns a real 401 InvalidJwtPayload. |
500 |
Local synthesis inside MockAPIServer |
No real traffic — you can't force prod to 500. |
Conn Err |
Local synthesis inside MockAPIServer |
Emits NSURLErrorNotConnectedToInternet. Equivalent to Android's DEAD_PORT trick. |
Proxied traffic lands in a real Iterable project. Use a dedicated test project to keep prod dashboards clean. The tester reads credentials from integration-test-app/config/test-config.json:
{
"jwtApiKey": "<JWT-enabled API key from your test project>",
"jwtSecret": "<HMAC secret from the same test project>",
"baseUrl": "https://api.iterable.com",
"projectId": "<your test project ID>"
}The JWT secret rotates on the Iterable project's settings page; if you regenerate it, update test-config.json and rebuild.
Once your local tests are passing:
- Review Results: Check the HTML reports in the
reports/folder - Validate in Iterable: Log into your Iterable dashboard to see test data
- Deploy with Confidence: Your integration is ready for production
- Set Up CI/CD: Use these tests in your automated deployment pipeline
Need More Help?
- Contact your Iterable Customer Success Manager
- Check the Iterable Support Center
- Review the technical documentation in this repository
Happy Testing! 🧪✨



