Skip to main content
The surveys module lets you collect user feedback through in-app surveys. Surveys can trigger automatically based on events (like in-app messages) or be presented manually from your code.

How It Works

Surveys are configured in the Console with content, question types, and trigger rules. Like in-app messages, they can appear automatically when trigger conditions are met — no code required for trigger-based surveys.

Present a Survey Manually

AppDNA.surveys.present("nps_q1_2026")

Module Access

let surveys = AppDNA.surveys

Module Methods

MethodSignatureDescription
presentpresent(_ surveyId: String)Present a survey manually
setDelegatesetDelegate(_ delegate: AppDNASurveyDelegate?)Set a delegate for survey callbacks

8 Question Types

Surveys support the following question types, configured in the Console:
TypeDisplayResponse
nps0-10 numeric scaleInteger 0-10
csat1-5 satisfaction scaleInteger 1-5
ratingStar ratingInteger 1-5
emoji_scaleEmoji optionsSelected emoji value
yes_noBinary choiceBoolean
single_choiceRadio button optionsSelected option string
multi_choiceCheckbox optionsArray of selected strings
free_textText input fieldFree-form string
Question types and their content are defined entirely in the Console. The SDK renders them automatically based on the survey configuration.

AppDNASurveyDelegate

Implement the delegate to capture survey responses and lifecycle events:
protocol AppDNASurveyDelegate {
    func onSurveyPresented(surveyId: String)
    func onSurveyCompleted(surveyId: String, responses: [SurveyResponse])
    func onSurveyDismissed(surveyId: String)
}

SurveyResponse

struct SurveyResponse {
    let questionId: String
    let answer: Any  // String, Int, [String], Bool depending on question type
}

Example Implementation

class FeedbackHandler: AppDNASurveyDelegate {
    func onSurveyPresented(surveyId: String) {
        print("Survey shown: \(surveyId)")
    }

    func onSurveyCompleted(surveyId: String, responses: [SurveyResponse]) {
        for response in responses {
            if let score = response.answer as? Int {
                if score >= 9 {
                    // Promoter -- show referral prompt
                    showReferralPrompt()
                } else if score <= 6 {
                    // Detractor -- show support link
                    showSupportLink()
                }
            } else if let feedback = response.answer as? String {
                print("User feedback: \(feedback)")
            }
        }
    }

    func onSurveyDismissed(surveyId: String) {
        print("Survey dismissed: \(surveyId)")
    }
}

AppDNA.surveys.setDelegate(FeedbackHandler())

Rich Media

Survey questions support rich media content configured in the Console:
  • Header images — add images above survey questions
  • Icons in options — use icon references in choice options (Lucide, SF Symbols, Material, or emoji)
  • Thank-you animations — Lottie or confetti effects on survey completion
  • Haptic feedback — triggered on option selection and submission
See the Rich Media guide for details on supported formats.

Auto-Tracked Events

EventTrigger
survey_presentedA survey is displayed
survey_response_submittedUser submits a survey response
survey_dismissedSurvey is closed without completing

Full Example

import AppDNASDK

class FeedbackManager: AppDNASurveyDelegate {
    init() {
        AppDNA.surveys.setDelegate(self)
    }

    /// Present NPS survey after a key moment
    func askForFeedback() {
        AppDNA.surveys.present("nps_q1_2026")
    }

    // MARK: - AppDNASurveyDelegate

    func onSurveyPresented(surveyId: String) {
        // Survey is visible
    }

    func onSurveyCompleted(surveyId: String, responses: [SurveyResponse]) {
        // React to feedback
        if let nps = responses.first(where: { $0.questionId == "nps_question" }),
           let score = nps.answer as? Int {
            if score >= 9 {
                showReferralPrompt()
            } else if score <= 6 {
                showSupportLink()
            }
        }
    }

    func onSurveyDismissed(surveyId: String) {
        // User dismissed without responding
    }
}
Surveys are created in the Console under Feedback > Surveys. Trigger-based surveys appear automatically — manual presentation with present() is for cases where you want precise control over timing.