Test Flow
The SDK provides a complete pre-built UI for conducting ANS challenge tests.
Presenting the Test Flow
- iOS
- Android
class ViewController: UIViewController, ANSChallengeDelegate {
func startTest() {
sdk.presentANSChallenge(
from: self,
configuration: .default,
animated: true
)
}
func ansChallengeDidStart(_ sdk: AutonomicHealthSDK) {
print("Test started")
}
func ansChallengeDidComplete(_ sdk: AutonomicHealthSDK, result: ANSTestResult) {
print("Test completed: \(result.testId)")
}
func ansChallengeDidCancel(_ sdk: AutonomicHealthSDK, reason: ANSCancellationReason) {
print("Test cancelled: \(reason)")
}
}
class MainActivity : AppCompatActivity(), TestFlowListener {
fun startTest() {
sdk.presentANSChallenge(
activity = this,
configuration = ANSTestConfiguration.default(),
animated = true
)
}
override fun onTestStarted() {
println("Test started")
}
override fun onTestCompleted(result: ANSTestResult) {
println("Test completed: ${result.testId}")
}
override fun onTestCancelled(reason: CancellationReason) {
println("Test cancelled: $reason")
}
}
Test Phases
The ANS Challenge test follows a carefully designed three-phase structure: Pre-Test, Test Execution, and Post-Test. Each phase is critical for clinical validity.
Pre-Test Phase
The pre-test phase prepares the patient and equipment for valid ANS testing. This phase cannot be skipped or modified.
1. Device Setup & Pairing
The SDK presents a device scanning screen that:
- Scans for all wearables enabled during SDK initialization (Polar, Garmin, BLE, Apple Watch)
- Displays available devices with signal strength (RSSI) indicators
- Shows battery level for compatible devices
- Provides real-time connection status
If this is not the first time the user has taken a test, the most recent device used successfully will be pre-selected with a status indicator showing connection status. This reduces friction for repeat testing.
The device selection is saved to local storage (UserDefaults on iOS, SharedPreferences on Android) and automatically restored when the test flow is presented again.
User Actions:
- Select a heart rate monitor from the list
- Wait for successful Bluetooth connection
- Verify battery level is sufficient (SDK warns if < 20%)
Connection States:
- 🔍 Scanning: Searching for nearby devices
- 🔗 Connecting: Establishing Bluetooth connection
- ✅ Connected: Device ready for testing
- ❌ Disconnected: Connection lost, must reconnect
A user can only pair one device at a time per test. If multiple heart rate monitors are worn (e.g., chest strap + watch), only one can be selected for data collection to avoid conflicting timestamps.
2. Safety Attestation
Before testing begins, users must confirm safety prerequisites:
Required Confirmations:
- Another adult is present during the test (required for standing challenge safety)
- User has not consumed caffeine, nicotine, or stimulants within the past 4 hours
- User has not exercised vigorously within the past 2 hours
- User is not currently experiencing dizziness, chest pain, or shortness of breath
- User understands they should stop the test if they feel faint, dizzy, or unwell
Users see prominent warnings to immediately stop the test if they experience:
- Chest pain or pressure
- Severe dizziness or lightheadedness
- Shortness of breath
- Rapid or irregular heartbeat
- Nausea or vomiting
- Vision changes or tunnel vision
These warnings are shown both on-screen and via voice-over for accessibility.
3. Challenge Reminder
Users are briefed on the 4 ANS challenges they'll encounter:
- Baseline (Resting): Sit or lie still, breathe normally
- Deep Breathing: Follow on-screen breathing prompts (inhale 5s, exhale 5s)
- Valsalva Maneuver: Blow into closed mouth/nose to create pressure (bear down)
- Standing Challenge: Stand still for extended period, minimize movement
Explaining challenges before the test (rather than during) prevents autonomic anticipation. For example, someone with POTS might have a sympathetic spike if they read "Get Ready to Stand" seconds before standing, contaminating baseline measurements.
Important Instructions Highlighted:
- Stay as still as possible during baseline
- Breathe at the pace shown on screen during deep breathing phase
- Do not talk or move unnecessarily during any phase
- Keep eyes on the screen for visual cues
4. Camera Positioning & Permission Grant
The final pre-test step sets up video recording for test validation.
Camera & Microphone Permissions: Users grant camera and microphone access if they haven't already. These permissions are required for test validity.
iOS Permission Strings:
NSCameraUsageDescription: "Video recording for test validation"NSMicrophoneUsageDescription: "Audio recording for test verification"
Android Permissions:
android.permission.CAMERAandroid.permission.RECORD_AUDIO
Positioning Requirements: The SDK displays a front-facing camera preview with on-screen guidance:
- Both the patient and companion must be visible in the frame
- Camera should be propped up on a stable surface (table, desk)
- Patient should be 3-5 feet from the camera
- Lighting should be adequate to see patient clearly
What the Video Captures:
- Patient positioning changes (sitting → standing)
- Body movements or fidgeting that could affect data quality
- Notable events (coughing, talking, phone interruptions)
- Companion presence confirmation
- Valsalva maneuver technique verification
Videos are stored locally on the device until upload completes, then automatically deleted. Videos are encrypted during transmission and stored securely in HIPAA-compliant cloud storage. Only the reviewing physician can access the video.
User Actions:
- Position camera to include both patient and companion
- Verify preview shows both people clearly
- Tap "Begin Test" to start recording and enter test phase
Test Execution Phase
The test phase is a fully automated, timed sequence of ANS challenges. The UI and protocols cannot be modified to ensure clinical validity across all tests.
Test Architecture
The test uses a horizontal page controller (similar to a wizard) that progresses through phases automatically:
- Baseline (resting)
- Deep Breathing
- Rest After Breathing
- Valsalva Maneuver
- Rest After Valsalva
- Standing Challenge
Phase Durations (Default):
- Baseline: 4 minutes
- Deep Breathing: 1 minute
- Rest After Breathing: 30 seconds
- Valsalva: 20 seconds
- Rest After Valsalva: 30 seconds
- Standing: 4 minutes
These durations are defaults and may be adjusted by the server-side test configuration based on clinical context. For example:
- POTS assessment may extend standing to 10+ minutes
- Follow-up tests may have shorter baseline if recent data exists
- First-time users may have longer baseline to establish individual norms
Pseudo-Random Timer Display
To prevent autonomic anticipation, the timer display flashes in and out at pseudo-random intervals.
Timer Flash Configuration:
- Minimum Interval: 8 seconds (time between timer appearances)
- Maximum Interval: 25 seconds
- Flash Duration: 2.5 seconds (how long timer is visible)
Why This Matters: If users could see a countdown timer continuously, they would anticipate challenge transitions. For example:
- Seeing "30 seconds remaining" in baseline → user prepares mentally to stand → sympathetic activation before standing begins
- This contamination invalidates the orthostatic challenge measurement
The pseudo-random timer keeps users vaguely aware of time (to stay engaged) but prevents anticipation of specific challenges.
The test never displays phrases like "Get Ready to Stand" or "Valsalva Coming Up" because:
- Patients with POTS may have sympathetic spikes from merely reading about standing
- Anticipatory anxiety activates the sympathetic nervous system prematurely
- Clinical validity requires capturing reflexive autonomic responses, not prepared ones
Data Collection During Test
Sensor Data Streams (Collected Continuously):
- RR Intervals: Beat-to-beat heart timing in milliseconds (primary ANS signal)
- Heart Rate: Beats per minute calculated from RR intervals
- Accelerometer Data: Device motion to detect artifacts (movement, poor contact)
- Motion Data: Device accelerometer + gyroscope to track body position changes
- Video Recording: Synchronized front-facing camera recording at 30 FPS
- Timestamps: All data streams synchronized to a common timeline
Why Motion Data Matters: Motion sensors detect:
- Body position changes: Transition from sitting to standing (confirms challenge compliance)
- Fidgeting or movement: Artifacts that may invalidate portions of the test
- Device displacement: Heart rate monitor shifting during movement
- Fall detection: Safety monitoring during standing challenge
All sensor streams are timestamped relative to a single test start time (Unix milliseconds). This enables precise alignment during analysis to correlate heart rate changes with body movements, breathing patterns, and video frames.
Visual & Audio Cues
On-Screen Display:
- Phase Name: "Baseline", "Deep Breathing", "Standing"
- Instructions: Text and animation showing what to do
- Breathing Pacer: Visual metronome for deep breathing phase (inhale circle grows, exhale circle shrinks)
- Timer (pseudo-random): Occasional display of elapsed time
- Connection Status: Heart rate monitor battery and connection indicator
Voice-Over Narration:
- Accessibility feature for visually impaired users
- Announces phase transitions: "Baseline phase complete. Now entering deep breathing."
- Provides breathing cues: "Breathe in... breathe out..."
- Does not announce upcoming challenges to prevent anticipation
Animations:
- Breathing Circle: Expands/contracts at 0.1 Hz (6 breaths/minute) during deep breathing
- Standing Indicator: Silhouette animation showing transition from sitting to standing
- Valsalva Visual: Bear-down graphic with pressure gauge
The test UI, timing, and instructions cannot be modified by integrating applications. This ensures clinical validity and regulatory compliance. All tests must follow identical protocols for results to be comparable.
User Engagement
To keep users engaged during the 10+ minute test:
- Subtle animations (breathing circle, progress indicators)
- Occasional timer flashes (user knows they're progressing)
- Voice-over encouragement: "You're doing great, stay still"
- Heart rate display (users can see their BPM in real-time)
What Users Cannot See:
- Exact time remaining (prevents anticipation)
- Upcoming challenges (preserves reflexive responses)
- Real-time HRV metrics or analysis (prevents biofeedback effects)
Post-Test Phase
After the standing challenge completes, the test automatically transitions to the post-test phase.
Automatic Data Upload
The SDK immediately begins uploading collected data:
Upload Sequence:
- Heart Rate Data: RR intervals and heart rate time series (typically 1-5 MB)
- Motion Data: Accelerometer/gyroscope streams (typically 500 KB - 2 MB)
- Video Recording: Compressed video file (typically 50-200 MB)
- Metadata: Test configuration, device info, timestamps, battery levels (< 100 KB)
Upload Progress: Users see a progress bar with status:
- "Uploading heart rate data... 50%"
- "Uploading motion data... 75%"
- "Uploading video... 90%"
Your app can track upload progress via delegate methods:
func ansChallenge(_ sdk: AutonomicHealthSDK,
uploadDidProgress progress: Double) {
// progress is 0.0 to 1.0
updateProgressBar(progress)
}
Use this for analytics or to display custom progress UI outside the SDK's modal flow.
Upload Failure Handling:
- SDK automatically retries failed uploads (exponential backoff)
- If network is unavailable, data is cached locally and retried later
- Users can dismiss the view and upload continues in background
- Webhook notification sent when upload completes (even if app is closed)
Validity Assessment
After upload completes, the SDK displays an initial validity assessment:
Validity Checklist: ✅ Connection Quality: Heart rate monitor maintained stable connection throughout test ✅ Data Completeness: All 6 phases have sufficient RR interval samples ✅ Motion Artifacts: Accelerometer data shows acceptable movement levels ✅ Video Quality: Video captured successfully with adequate lighting ✅ Phase Compliance: User followed instructions for each challenge
Possible Issues Flagged: ⚠️ Excessive Movement: Motion artifacts detected during baseline or deep breathing ⚠️ Connection Drops: Heart rate monitor disconnected briefly during test ⚠️ Incomplete Phases: User skipped or abbreviated a challenge ⚠️ Poor Video Quality: Lighting too dark or camera obstructed ⚠️ Talking During Test: Audio detected during phases requiring silence
The SDK's automatic validity check is preliminary. The final determination of test validity is made by the reviewing physician, who watches the video and examines the full data set.
A test that passes automatic checks may still be rejected by a physician if they observe:
- Poor Valsalva technique (not enough pressure)
- Leaning or holding onto furniture during standing
- Distraction or non-compliance visible in video
- Data patterns inconsistent with video observations
Notable Events
The post-test screen lists notable events detected during the test:
Automatically Detected Events:
- Coughing (audio detection)
- Talking (audio detection)
- Sudden movements (accelerometer spikes)
- Connection interruptions (Bluetooth drops)
- Phone calls or notifications (if detectable)
- Battery warnings (device battery < 15%)
Why Notable Events Matter: Physicians review these events to determine if they invalidate specific test segments. For example:
- Coughing during deep breathing may invalidate parasympathetic measurements
- Talking during baseline creates movement artifacts
- Phone interruptions may cause sympathetic activation
Manual Event Logging (Future Feature): Users may be able to manually log events:
- "I sneezed during baseline"
- "I had to adjust the heart rate monitor"
- "I felt dizzy around the 5-minute mark"
View Dismissal
When the user closes the post-test view:
- The test flow modal is dismissed
- Your app receives a delegate callback:
ansChallengeDidComplete(_ sdk:result:) - The
ANSTestResultobject contains thetestIdfor future reference - Video and sensor data files are automatically cleaned up from local storage
You can and should cache the returned testId locally. This allows you to:
- Check test review status later via the API
- Fetch results when physician review is complete
- Display historical test list to users
Remember: You can cache IDs only, not the actual test data or results. See Caching Policy for details.
What Happens Next?
After dismissal, the test enters the physician review queue:
-
Backend Processing (5-15 minutes):
- ANS analysis algorithms compute RFa, LFa, sympathovagal balance for each phase
- Validity checks run on sensor data quality
- Video is transcoded and prepared for physician viewing
-
Physician Review (24-72 hours typical):
- Licensed healthcare provider watches video
- Reviews all 6 phases of RR interval data
- Confirms test validity and compliance
- Interprets ANS metrics in clinical context
- Creates treatment plan if appropriate
-
Review Complete:
- Test status changes to
reviewedorrequires_retest - If reviewed: Treatment plan becomes available via API
- If retest needed: Feedback provided on what went wrong
- Webhook notification sent to your configured endpoint
- Test status changes to
Configure webhooks in the Developer Portal to receive real-time notifications when test review status changes. This provides better UX than polling the API.
See API Reference - Webhook Configuration for implementation details.
Hooks & Analytics
- iOS
- Android
extension ViewController: ANSChallengeDelegate {
func ansChallenge(_ sdk: AutonomicHealthSDK,
didStartPhase phase: ANSTestPhase) {
analytics.log("phase_started", parameters: ["phase": phase.rawValue])
}
func ansChallenge(_ sdk: AutonomicHealthSDK,
uploadDidProgress progress: Double) {
updateProgressBar(progress)
}
}
override fun onPhaseStarted(phase: ANSTestPhase) {
analytics.log("phase_started", mapOf("phase" to phase.name))
}
override fun onUploadProgress(progress: Float) {
updateProgressBar(progress)
}
You cannot:
- Modify, overlay, or add UI elements to the test flow screens
- Intercept or access sensor data during the test
- Pause, skip, or reorder test phases
- Adjust phase durations or timing
- Disable video recording or audio capture
- Modify instructions, animations, or voice-over narration
These restrictions ensure clinical validity and regulatory compliance. All ANS tests must follow identical protocols for results to be medically comparable.
However, you can:
- Receive delegate callbacks for test lifecycle events (started, completed, cancelled)
- Receive delegate callbacks for phase transitions (for analytics only)
- Track upload progress
- Cache the returned test ID after completion
- Fetch test results via API after physician review
Next Steps
Continue to Form Requirements for required questionnaires.