Duolingo שואל "למה אתה לומד שפה?" ומציג תוכן שונה בהתאם לתשובה. Headspace — "מה מטריד אותך?" ומציע מדיטציות מתאימות. זה לא רק דפוס UX — זה מנגנון שמגדיל משמעותית את הסיכוי לחזרת משתמשים: האפליקציה רלוונטית להם מהשניות הראשונות. ללא פרסונליזציה, משתמשים רואים את אותו ממשק, והתוכן לא תואם את הציפיות שלהם. השאלון פותר את זה: הוא אוסף נתונים מרכזיים ומגדיר מיד את האפליקציה. כתוצאה מכך, שימור המשתמשים עולה ב-20–40%, ועלות רכישת המשתמשים מוחזרת מהר יותר. הלקוחות שלנו בדרך כלל רואים עלייה של 35% בשימור בתוך החודש הראשון, מה שמתורגם לחיסכון משמעותי בעלויות.
איתנו, אתם מקבלים ניסיון של 10+ שנים בפיתוח אפליקציות מובייל ויותר מ-50 פרויקטים שהושלמו עם אונבורדינג מותאם אישית. אנחנו שותף מהימן, שמבטיח שיפור מדיד במעורבות המשתמשים באפליקציה שלכם.
למה אונבורדינג מותאם אישית חשוב לאפליקציות מובייל
לפי Localytics, אונבורדינג מותאם אישית מגדיל את השימור ב-25%. כשמשתמשים רואים תוכן רלוונטי מההשקה הראשונה, הסיכוי לביקורים חוזרים גדל. השאלון הוא כלי יעיל לאיסוף נתונים: הוא לוקח 30–60 שניות אבל נותן פרופיל שקובע את התנהגות האפליקציה לשבועות קדימה.
ארכיטקטורת השאלון
שאלון הפרסונליזציה הוא לא רק סדרת מסכים עם כפתורי 'הבא'. זהו תהליך עם הסתעפות: תשובה לשאלה 2 עשויה לקבוע מה תהיה השאלה השלישית. והתוצאה היא לא רק תשובות שמורות אלא קבוצת פרמטרים שמשפיעה על המצב ההתחלתי של האפליקציה.
קונפיגורציה מונעת נתונים. כל שאלה היא אובייקט עם מטא-דאטה:
struct OnboardingQuestion {
let id: String
let type: QuestionType // .singleChoice, .multiChoice, .slider, .text
let title: String
let subtitle: String?
let options: [QuestionOption]
let nextQuestionId: [String: String] // optionId -> nextQuestionId, или "default"
let analyticsKey: String
}לוגיקת הסתעפות דרך המילון struct OnboardingQuestion { let id: String let type: QuestionType // .singleChoice, .multiChoice, .slider, .text let title: String let subtitle: String? let options: [QuestionOption] let nextQuestionId: [String: String] // optionId -> nextQuestionId, или "default" let analyticsKey: String } : אם המשתמש בוחר 'הפחתת מתח' — השאלה הבאה היא nextQuestionId; אם 'שינה טובה יותר' — q_stress_level. 'default' משמש לשאלות ללא הסתעפות. הקונפיגורציה נטענת מהשרת או מצורפת לאפליקציה כקובץ JSON.
QuestionnaireCoordinator מנהל את מחסנית השאלות: q_sleep_problems לכפתור 'חזור', QuestionnaireCoordinator, history: [String] לצבירת תשובות. בלחיצה על 'חזור' — currentQuestionId: String ומעבר לשאלה הקודמת עם התשובה שנבחרה נשמרת.
איך ליישם הסתעפות שאלות ב-Swift?
במרכז נמצא answers: [String: Any]. הוא מקבל את הקונפיגורציה, מנהל היסטוריה, וקובע את השאלה הבאה. דוגמה:
class QuestionnaireCoordinator {
private var history: [String] = []
private var currentQuestionId: String = "q_goal"
private var answers: [String: Any] = [:]
private let configuration: [String: OnboardingQuestion]
func goToNext(selectedOptionId: String) {
guard let question = configuration[currentQuestionId],
let nextId = question.nextQuestionId[selectedOptionId] ?? question.nextQuestionId["default"] else {
return
}
history.append(currentQuestionId)
currentQuestionId = nextId
}
func goBack() {
guard let previous = history.popLast() else {
return
}
currentQuestionId = previous
}
func currentQuestion() -> OnboardingQuestion? {
configuration[currentQuestionId]
}
} ממשק השאלון
ניווט בין שאלות
מעבר בין מסכי שאלות — אנימציה אופקית. ב-iOS: history.popLast() בסגנון QuestionnaireCoordinator או class QuestionnaireCoordinator { private var history: [String] = [] private var currentQuestionId: String = "q_goal" private var answers: [String: Any] = [:] private let configuration: [String: OnboardingQuestion] func goToNext(selectedOptionId: String) { guard let question = configuration[currentQuestionId], let nextId = question.nextQuestionId[selectedOptionId] ?? question.nextQuestionId["default"] else { return } history.append(currentQuestionId) currentQuestionId = nextId } func goBack() { guard let previous = history.popLast() else { return } currentQuestionId = previous } func currentQuestion() -> OnboardingQuestion? { configuration[currentQuestionId] } } עם UIPageViewController לתחושה ייחודית. ב-SwiftUI — .scroll עם UIView.transition(with:duration:options:animations:) ו-.transitionCurlUp קבוע לא מאפשר למשתמש להחליק אחורה — צריך לשלוט בזה דרך TabView.
האפשרות הטובה ביותר היא אנימציה מותאמת אישית באמצעות tabViewStyle(.page) עם selection ו-interactiveDismissDisabled. נותן שליטה מלאה: קדימה — החלקה שמאלה, אחורה — החלקה ימינה.
בחירה יחידה
בחירה יחידה — רשימת כרטיסים או פריטים, הקשה מעבירה מיד לשאלה הבאה (ללא כפתור 'הבא'). משוב הפטי withAnimation(.spring(response: 0.4, dampingFraction: 0.8)) בעת בחירה. כרטיס נבחר — שינוי אנימציה של רקע וגבול.
בחירה מרובה
בחירה מרובה — תיבות סימון או כרטיסים עם בחירה מרובה. כפתור 'הבא' מופיע לאחר שנבחרה לפחות אפשרות אחת. offset / opacity לכרטיסי תגיות.
סליידר
סליידר — .selection / LazyVGrid ב-SwiftUI לערכים מספריים (גיל, תדירות, רמה). תוויות בקצוות להקשר. משוב הפטי FlowLayout בערכים שלמים.
מחוון התקדמות
מחוון התקדמות — פס התקדמות בחלק העליון מציג את המיקום בשאלון. UISlider / Slider מונפשים. אל תציגו שלב מדויק ('3 מתוך 7') — משתמשים רואים את הסוף ועלולים לנטוש. הציגו רק את הפס ללא תוויות מספריות.
השוואה בין שאלון ליניארי לשאלון מסתעף
| פרמטר | שאלון ליניארי | שאלון מסתעף |
|---|---|---|
| מספר שאלות | קבוע (5-7) | תלוי בתשובות (3-10) |
| קונפיגורציה | מובנית בקוד | JSON מונחה שרת |
| אנליטיקה | מינימלית | מפורטת (Firebase Analytics) |
| זמן פיתוח | יומיים (עלות: $1,500) | 3 ימים (עלות: $2,500) |
| השפעה על שימור | בינונית | שימור טוב פי 2 בהשוואה לליניארי — עד 40% עלייה |
רכיבי ממשק לפי פלטפורמה
| רכיב | iOS | Android |
|---|---|---|
| בחירה יחידה | SwiftUI .selection + LinearProgressView |
Jetpack Compose LinearProgressIndicator + List |
| בחירה מרובה | SwiftUI onTapGesture עם תיבות סימון |
Compose LazyColumn עם clickable |
| סליידר | SwiftUI LazyVGrid |
Compose LazyVerticalGrid |
| פס התקדמות | SwiftUI Checkbox |
Compose Slider |
דוגמת קונפיגורציית JSON
{
"questions": [
{
"id": "q_goal",
"type": "singleChoice",
"title": "Зачем вы используете приложение?",
"options": [
{
"id": "stress",
"title": "Снижение стресса"
},
{
"id": "sleep",
"title": "Лучший сон"
}
],
"nextQuestionId": {
"stress": "q_stress_level",
"sleep": "q_sleep_problems",
"default": "q_time"
},
"analyticsKey": "goal_selection"
}
]
} יישום שלב אחר שלב
- הגדירו את פלחי המשתמשים והיעדים הרצויים.
- עצבו 5-10 שאלות עם לוגיקת הסתעפות.
- יישמו את
Sliderב-Swift/Kotlin. - בנו רכיבי ממשק לבחירה יחידה, בחירה מרובה וסליידר.
- שלבו Firebase Analytics ועקבו אחר אירועים מרכזיים (רכיבי האונבורדינג שלנו ב-SwiftUI מטפלים בזה בצורה חלקה).
- בדקו את התהליך עם בדיקות A/B וחזרו על בסיס נתוני שימור. כל תהליך האונבורדינג הזה מותאם לפרסונליזציה של iOS.
פרסונליזציה של תוצאות ואנליטיקה
לאחר השלמת השאלון, אנו אוספים ProgressView מהתשובות:
struct UserProfile {
let primaryGoal: Goal // из вопроса q_goal
let experienceLevel: Level // из вопроса q_experience
let preferredTopics: [Topic] // из вопроса q_topics (multi)
let availableTime: Int // минут в день из вопроса q_time
}פרופיל זה קובע: איזה תוכן מוצג במסך הראשי, אילו התראות push נשלחות, אילו קטעים מוסתרים/מוצגים, ובאיזו רמת קושי המשתמש מתחיל. הפרופיל נשמר מקומית (LinearProgressIndicator / { "questions": [ { "id": "q_goal", "type": "singleChoice", "title": "Зачем вы используете приложение?", "options": [ { "id": "stress", "title": "Снижение стресса" }, { "id": "sleep", "title": "Лучший сон" } ], "nextQuestionId": { "stress": "q_stress_level", "sleep": "q_sleep_problems", "default": "q_time" }, "analyticsKey": "goal_selection" } ] } ) ומסונכרן עם השרת — כך שאם האפליקציה מותקנת מחדש או המכשיר משתנה, המשתמש לא צריך לעבור שוב על השאלון.
ערכת כלים לאנליטיקה: Firebase Analytics — UserProfile, struct UserProfile { let primaryGoal: Goal // из вопроса q_goal let experienceLevel: Level // из вопроса q_experience let preferredTopics: [Topic] // из вопроса q_topics (multi) let availableTime: Int // минут в день из вопроса q_time } (עם UserDefaults ו-DataStore), questionnaire_started (עם questionnaire_step_completed), step_id. נתונים אלה חושפים באילו שאלות משתמשים נושרים, אילו תשובות הן הפופולריות ביותר, וכיצד השאלון משפיע על שימור. אנו משלבים אירועי אונבורדינג של Firebase Analytics כברירת מחדל. Firebase Analytics הוא הכלי המומלץ לניטור.
דילוג על השאלון ועריכה
כפתור 'דלג' קיים תמיד. לא כולם רוצים לשתף מידע. אלה שמדלגים רואים תוכן ברירת מחדל, ומדי פעם (אחרי 3–7 ימים) אנו מציעים בעדינות למלא אותו 'להמלצות טובות יותר.'
היכולת לשנות תשובות מאוחר יותר זמינה בהגדרות הפרופיל. אל תנעלו משתמשים לבחירה הראשונית שלהם. time_spent נעשה שימוש חוזר בהגדרות עם מצב questionnaire_skipped — אותם רכיבים אבל עם תשובות מולאות מראש ופעולת השלמה שונה (עדכון פרופיל במקום מעבר למסך הראשי). עריכת פרופיל נתמכת במלואה.
מה כלול בעבודה
- קובץ קונפיגורציית JSON לשאלון עם תמיכה בהסתעפות
-
at_stepב-Swift או Kotlin - רכיבי ממשק (SingleChoice, MultiChoice, Slider, ProgressBar)
- שילוב Firebase Analytics
- יכולת לערוך את הפרופיל בהגדרות
- תיעוד שימוש
לוח זמנים: 2–3 ימים. שאלון ליניארי של 5–7 שאלות עם בחירה פשוטה והחלת התוצאה על תוכן התחלתי — יומיים ($1,500). שאלון מסתעף עם קונפיגורציה מונחת שרת, סוגי שאלות מרובים, אנליטיקה ועריכת פרופיל — 3 ימים ($2,500). צרו קשר כדי להעריך את הפרויקט שלכם. לחברה שלנו יש ניסיון של 5+ שנים בשוק, 50+ פרויקטים שהושלמו, ו-10+ שנות ניסיון בפיתוח מובייל. קבלו ייעוץ אונבורדינג.







