קיבלת משימה: ממשק מותאם אישית להתראת push ב-iOS עם מפת משלוח וכפתורי "אישור"/"דחייה". ממשק ה-iOS הסטנדרטי לא מתאים —你需要 הרחבה משלך. הרחבה זו היא הדרך היחידה להוסיף תצוגה מקדימה אינטראקטיבית מבלי לפתוח את האפליקציה. לעיתים קרובות התצוגה המקדימה הסטנדרטית אינה מספיקה: צריך להציג מפה, טופס הזמנה או כפתור מותאם אישית. לשם כך, iOS מספקת מנגנון Notification Content Extension. עם זאת, ההתקנה שלו דורשת עבודה מדויקת עם UNNotificationCategory, הגדרה נכונה של Info.plist, והבנה של מגבלות ה-sandbox. במהלך השנים צברנו 12+ מקרי הצלחה — ממפות לוגיסטיקה ועד סקרים אינטראקטיביים.
מנגנון Notification Content Extension ל-iOS
Content Extension הוא יעד נפרד עם UIViewController משלו המיישם UNNotificationContentExtension. כאשר המשתמש מרחיב התראה עם הקטגוריה המתאימה, המערכת טוענת את ה-controller שלך וקוראת ל-didReceive(_:). כפתורי פעולה מתווספים דרך UNNotificationCategory באפליקציה הראשית. ה-payload חייב להכיל category עם אותו מזהה.
class NotificationViewController: UIViewController, UNNotificationContentExtension {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var bodyLabel: UILabel!
func didReceive(_ notification: UNNotification) {
let content = notification.request.content
titleLabel.text = content.title
bodyLabel.text = content.body
// парсим content.userInfo для дополнительных данных
}
func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {
// обработка нажатия на action buttons
completion(.dismissAndForwardAction)
}
} רישום קטגוריה ליישום Notification Content
יש לרשום את קטגוריית ההתראה לפני שליחת ההתראה הראשונה — בדרך כלל ב-class NotificationViewController: UIViewController, UNNotificationContentExtension { @IBOutlet weak var titleLabel: UILabel! @IBOutlet weak var bodyLabel: UILabel! func didReceive(_ notification: UNNotification) { let content = notification.request.content titleLabel.text = content.title bodyLabel.text = content.body // парсим content.userInfo для дополнительных данных } func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) { // обработка нажатия на action buttons completion(.dismissAndForwardAction) } } או דרך AppDelegate. מזהה הקטגוריה חייב להתאים ל-UNUserNotificationCenter.current().setNotificationCategories([...]) ב-Info.plist של ההרחבה.
הגדרת גודל ממשק מותאם אישית
הגובה מוגדר ב-Info.plist של ההרחבה דרך UNNotificationExtensionCategory (יחס גובה-רוחב). לדוגמה, Info.plist לכרטיס הזמנה. אם יש צורך בגובה דינמי, שנה את UNNotificationExtensionInitialContentSizeRatio בקוד. טכניקה זו מתאימה לתוכן משתנה — מהודעה קצרה ועד מפה עם מסלול. יחס הגובה נע בין 0.2 ל-0.8, ותומך בסוגי תוכן כמו טקסט, מפות וטפסים. גובה דינמי משמש ב-80% מהיישומים.
| סוג תוכן | InitialContentSizeRatio | preferredContentSize (בקוד) |
|---|---|---|
| טקסט עם כפתור אחד | 0.2 | 150x320 |
| מפה עם מסלול | 0.8 | 400x320 |
| טופס קלט | 0.5 | 300x320 |
קבצי מדיה נגישים דרך 0.6. אם Notification Service Extension הוריד מראש תמונה, Content Extension תציג אותה ב-preferredContentSize מותאם אישית ללא התצוגה המקדימה של המערכת.
הגבלת בקשות רשת
הגבלה זו היא מכוונת. הנתונים חייבים להגיע ב-payload (עד 4KB עבור APNs) או דרך קובץ מצורף. אם אתה צריך תוצאה חיה של משחק, עדכן את הממשק דרך notification.request.content.attachments — יישמנו זאת עבור אפליקציית ספורט, וזה עבד.
רכיבים אינטראקטיביים (UIImageView, UNUserNotificationCenter.current().getDeliveredNotifications()) נתמכים, אך הקשות מעובדות דרך UIButton, לא דרך IBAction. פרט זה שבר את פרויקט ה-UIKit הראשון של מתחיל. ב-SwiftUI זה קל יותר: השתמש ב-UITextField עם העברת פעולה דרך closure.
השוואה: UIKit מול SwiftUI
| מאפיין | UIKit | SwiftUI |
|---|---|---|
| גודל קוד | ~150 שורות | ~50 שורות (קצר ב-66%) |
| מורכבות אנימציה | בינונית | נמוכה (withAnimation) |
| תמיכת iOS | 10+ | 16+ |
| אינטראקטיביות | דרך delegation | דרך binding |
| מהירות פיתוח | איטי פי 2 | מהיר יותר (פחות boilerplate) |
יישום ה-SwiftUI משתמש בפי שלושה פחות שורות וקל יותר לתחזוקה, אך דורש iOS 16+. ממשק מותאם אישית יעיל פי 3 בהנעת פעולות משתמש מאשר באנרים סטנדרטיים של התראות. SwiftUI מקצר את זמן הפיתוח ב-50% בהשוואה ל-UIKit עבור ממשקי התראות מותאמים אישית.
איך לעדכן נתונים ללא רשת?
נצל App Groups לאחסון משותף. Notification Service Extension יכול לשמור נתונים עדכניים ב-container המשותף, ו-Content Extension יכול לקרוא אותם לפני התצוגה. לחלופין, העבר דגל קטן ב-payload וטען תוכן סטטי מה-bundle.
דוגמת payload למפת משלוח
{
"aps": {
"alert": {
"title": "Заказ #123",
"body": "Курьер выехал"
},
"category": "delivery_map"
},
"latitude": 53.9,
"longitude": 27.56,
"order_id": "123"
} מה כלול בעבודה במפתח מוכן
- יצירת יעד ההרחבה
- ממשק מותאם אישית (XIB, UIKit או SwiftUI) עם גובה אדפטיבי
- רישום
didReceive(_:completionHandler:)עם כפתורי פעולה (תומך עד 10 לקטגוריה) - טיפול בתגובות פעולה והעברת שליטה לאפליקציה
- הגדרת App Groups לגישת נתונים משותפת
- בדיקה על סימולטור ומכשיר אמיתי דרך TestFlight
תהליך עבודה
- אנליטיקה — הגדר סוגי התראות, מבנה payload, קטגוריות. הערך גרסאות iOS יעד.
- עיצוב — אב טיפוס UI/UX תוך התחשבות במגבלות (ללא רשת, payload של 4KB מקטין גודל ב-90% בהשוואה לסטנדרט). בחר UIKit או SwiftUI.
- יישום — פתח את ההרחבה ושלב עם האפליקציה הראשית. הגדר provisioning profiles.
- בדיקה — בדוק על מכשירים וגרסאות iOS שונות, כולל סימולציית push notification.
- פריסה — הכין App Store Connect, פרסם דרך TestFlight, סקירה סופית.
לוחות זמנים ואחריות
ממשק מותאם אישית בסיסי לסוג התראה אחד: בין יום ליומיים. עבור קטגוריות מרובות, רכיבים אינטראקטיביים ושילוב Service Extension: בין יומיים לשלושה. עלות אופיינית לסוג התראה אחד: $500–$1,000. אנו מבטיחים שהפתרון יעבור בדיקת App Store (סעיף 4.2). למהנדסים שלנו יש ניסיון של 5+ שנים ב-iOS. התקציב נקבע לאחר ניתוח — צור קשר להערכה. חיסכון ממוצע של 40% בזמן פיתוח בהשוואה לבנייה מאפס. עבור אפליקציית לוגיסטיקה אופיינית, יישום התראה מותאמת אישית עם מפה וכפתורי פעולה יכול לחסוך מעל $2,000 בעלויות פיתוח.
טעויות אופייניות ביישום
- שכחת להגדיר
onTapGestureב-Info.plist — ההרחבה לא תעבוד. - שימוש בחיבור רשת ישיר — קריסת ריצה.
- ניסיון לשנות גודל דרך constraints ללא התחשבות ב-
App Groups— נותן ממשק קטוע. - אי סנכרון מזהה קטגוריה בין האפליקציה הראשית להרחבה.
לפרטים נוספים על יכולות Content Extension, ראה תיעוד רשמי של Apple.
נעריך את הפרויקט שלך — צור קשר. הזמן שילוב במפתח מוכן, וניישם ממשק מותאם אישית לכל התראות push תוך התחשבות בכל מגבלות iOS.







