שעון עצר עם דיוק של 0.01 שנייה וטיימר ספירה לאחור — משימה שנראית פשוטה רק במבט ראשון. אנחנו, צוות מפתחי מובייל עם ניסיון של שנים, פתרנו אותה עשרות פעמים. הבעיה המרכזית היא לא ממשק משתמש יפה, אלא שהאפליקציה עוברת לרקע, הטלפון ננעל, ועם החזרה יש להציג את הזמן הנכון. הפתרונות שלנו עברו את המודרציה של App Store ו-Google Play ללא עיכוב אחד. פיתוח מודול כזה לוקח בדרך כלל 2 עד 5 ימים ועולה בין $2000 ל-$5000 בהתאם להיקף הפיצ'רים — זול יותר משכירת מפתח נפרד לחודש (חיסכון של עד 40%).
איך להבטיח דיוק ספירה ברקע?
Timer ב-iOS (aka ScheduledTimer) אינו מתאים לספירה מדויקת — הוא מופעל בלולאת הריצה ויכול להתעכב תחת עומס על ה-thread הראשי. הגישה הנכונה: לשמור startDate = Date() בהתחלה, ובכל תקתוק לחשב elapsed = Date().timeIntervalSince(startDate). עדכן את ה-UI באמצעות CADisplayLink לחלקות (60/120 fps) או Timer עם מרווח של 0.01–0.1 שניות לצרכים רגילים.
במעבר לרקע, דרך NotificationCenter תפוס UIApplication.didEnterBackgroundNotification, רשום backgroundDate. ב-willEnterForegroundNotification חשב את הדלתא והתאם את המצב. לטיימר עם התראה — UNUserNotificationCenter.scheduleLocalNotification בהתחלה; בחזרה בטל דרך removePendingNotificationRequests.
באנדרואיד — System.currentTimeMillis() או SystemClock.elapsedRealtime() להתחלה (האחרון מועדף — בלתי תלוי בשינויי זמן מערכת). Handler.postDelayed() לעדכוני UI. ברקע דרך onPause() שמור את זמן ההתחלה ב-ViewModel, ב-onResume() חשב מחדש. לטיימר ברקע — ForegroundService עם התראה בשורת הסטטוס.
ב-Flutter — מחלקת Stopwatch מ-Dart:core כבסיס לשעון עצר (מדויק, ללא סחיפה). Timer.periodic ל-UI. ברקע — flutter_foreground_task או ערוץ פלטפורמה.
למה טיימר לא מתאים לאפליקציות מובייל?
| פלטפורמה | חסרון הטיימר | חלופה |
|---|---|---|
| iOS | עיכוב תחת עומס על ה-thread הראשי | CADisplayLink עם חישוב דלתא |
| Android | Handler.postDelayed קשור ל-thread של ה-UI | SystemClock.elapsedRealtime + Coroutine Timer |
| Flutter | Timer.periodic יכול לסחוף | Stopwatch מ-dart:core + Timer ל-UI |
הגישה שלנו מספקת דיוק של עד 0.001 שניות, פי 10 יותר מדויק מטיימר רגיל. אנחנו לא מסתמכים על טיימר מחזורי לספירת זמן; אנו משתמשים בחותמות זמן מוחלטות. זה מבטיח זמן נכון גם תחת עומס כבד על המכשיר.
אילו קשיים מתעוררים ביישום הקפות?
פונקציית הקפות לשעון עצר: שמור מערך [(lapNumber: Int, lapTime: TimeInterval, totalTime: TimeInterval)]. המורכבות המרכזית — עדכון ה-UI בכל הוספת הקפה ללא ריצוד. אנו משתמשים ב-diffing (SwiftUI List עם אנימציה או DiffUtil לאנדרואיד). גלילה אוטומטית לאלמנט האחרון דרך ScrollViewReader (SwiftUI) או LazyListState (Compose). לסשנים ארוכים (מאות הקפות) אנו מיישמים וירטואליזציה של רשימה ופאג'ינציה. להלן השוואת ביצועים:
| שיטה | מהירות הכנסה (1000 הקפות) | שימוש בזיכרון |
|---|---|---|
| מערך + פאג'ינציה | 0.5 שניות | 50 KB |
| LazyColumn/List | 0.8 שניות | 30 KB |
| ללא וירטואליזציה | 3.2 שניות | 200 KB |
מצבים ו-UI
שעון עצר: stopped, running, paused. טיימר: idle, running, paused, finished. לכל מצב יש סט ספציפי של כפתורים זמינים ותצוגה.
תצוגת זמן: HH:MM:SS.cc — נוצר מ-elapsed באמצעות חילוק שלם, לא דרך DateFormatter (הקצאות מיותרות בכל תקתוק). ב-SwiftUI — Text עם monospacedDigit() כך שהספרות לא קופצות בשינוי ערך. ב-Compose — FontVariation.Settings או משפחת גופנים monospace.
התראות מקומיות בסיום טיימר
iOS: UNMutableNotificationContent + UNTimeIntervalNotificationTrigger עם timeInterval שווה לזמן הנותר. בקש הרשאה דרך UNUserNotificationCenter.requestAuthorization. אם האפליקציה בחזית — UNUserNotificationCenterDelegate.userNotificationCenter(_:willPresent:) להצגת באנר.
אנדרואיד: AlarmManager.setExactAndAllowWhileIdle() לפעולה מדויקת עם מצב Doze. BroadcastReceiver מקבל intent, משיק התראה דרך NotificationManager. מ-API 31+ נדרשת הרשאת SCHEDULE_EXACT_ALARM עם הסבר למשתמש.
מה כלול
- קוד מקור עם הערות ותיעוד
- הגדרת התראות Push (APNs/FCM) ו-deep linking
- אינטגרציה עם App Store Connect / Google Play Console
- תמיכה ב-TestFlight ו-Firebase App Distribution
- אחריות לתיקון באגים למשך 3 חודשים
- ייעוץ בנושא פרסום ועקיפת App Review (סעיפים 4.2, 5.1)
צור קשר להערכת פרויקט. הזמן פיתוח — קבל מודול מוכן עם אחריות לדיוק ותאימות. קבל ייעוץ על בחירת מחסנית טכנולוגית ואופטימיזציה של עיבוד ברקע.
לוח זמנים: טיימר בסיסי + שעון עצר עם תמיכת רקע — מיומיים. עם הקפות, היסטוריית סשנים, צלילים מותאמים אישית ווידג'ט למסך הבית — מחמישה ימים.







