الحلقة 7: سلوك المقدمة — التحكم في التجربة الحية
بشكل افتراضي، تقوم معظم أنظمة تشغيل الهواتف المحمولة بحجب "بانرات" (Banners) الإشعارات بينما يكون التطبيق مفتوحاً ونشطاً في المقدمة (Foreground). الفلسفة وراء ذلك هي أنه إذا كان المستخدم يشاهد تطبيقك بالفعل، فإنه ليس بحاجة لتنبيه منبثق يشتت انتباهه. ومع ذلك، هناك العديد من الحالات التي تريد فيها ظهور هذا التنبيه — فكر في تنبيه حرج أو رسالة جديدة من غرفة دردشة مختلفة.
في هذا الدرس، سنحترف:
- معالج الإشعارات (Notification Handler): الحارس الأمامي للتنبيهات في المقدمة.
- تخصيص السلوك: تحديد ماهية الإشعارات التي تظهر كبانرات، أو تشغل أصواتاً، أو تحدث الشارات (Badges) ديناميكياً.
- المستقبلات داخل التطبيق: استخدام المستمعين لتحديث واجهة المستخدم فورياً دون الحاجة لبانرات.
- أفضل ممارسات تجربة المستخدم (UX): التوازن بين التفاعل ومقاطعة المستخدم.
معالج الإشعارات (Notification Handler)
في إكسبو، نستخدم setNotificationHandler لتعريف كيفية استجابة التطبيق للإشعارات التي تصل بينما يكون التطبيق مفتوحاً. هذا تكوين عالمي يجب تعيينه في بداية دورة حياة تطبيقك.
index.tstypescriptimport * as Notifications from 'expo-notifications'; Notifications.setNotificationHandler({ handleNotification: async (notification) => { // مراجعة الإشعار القادم const { title } = notification.request.content; const isUrgent = title?.includes('هام'); return { shouldShowAlert: isUrgent, // إظهار بانر فقط للعناصر الهامة shouldPlaySound: true, // تشغيل الصوت دائماً shouldSetBadge: false, // عدم تحديث شارة أيقونة الشاشة الرئيسية }; }, });
تحديث واجهة المستخدم داخلياً
حتى لو اخترت عدم إظهار بانر (shouldShowAlert: false)؛ فستظل تريد أن يكون تطبيقك على دراية بالبيانات الجديدة. لهذا، نستخدم addNotificationReceivedListener.
هذا الخيار مثالي لـ "التحديثات الصامتة"، مثل إظهار مؤشر "رسالة جديدة" أو تحديث قائمة المهام دون مقاطعة تدفق المستخدم الحالي.
index.tstypescriptuseEffect(() => { const subscription = Notifications.addNotificationReceivedListener(notification => { const data = notification.request.content.data; console.log("تم استلام إشعار في المقدمة:", data); // تحديث الحالة المحلية أو إعادة جلب البيانات if (data.type === 'REFRESH_DATA') { refreshMyData(); } }); return () => subscription.remove(); }, []);
تجربة المستخدم: فن عدم المقاطعة
إن الإفراط في استخدام البانرات المنبثقة في المقدمة هو أسرع طريقة لإزعاج المستخدمين. اتبع هذه الإرشادات الاحترافية:
- الوعي بالسياق: إذا كان المستخدم يشاهد "المشروع أ"، فلا تظهر بانراً لتعليق جديد على "المشروع أ". فقط قم بتحديث العرض.
- البانرات الانتقائية: استخدم
shouldShowAlert: trueفقط للأحداث خارج السياق الحالي (مثل رسالة من مستخدم آخر) أو التنبيهات الحساسة للوقت. - التحديثات الصامتة: استخدم المستمعين للحفاظ على حيوية التطبيق بصمت. سيقدر المستخدم الشعور بـ "البث المباشر" دون الملوثات البصرية المستمرة.
التنفيذ في مشروعك
في سيناريو واقعي، قد ترغب في تبديل السلوكيات بناءً على الشاشة النشطة حالياً:
index.tstypescriptNotifications.setNotificationHandler({ handleNotification: async (notification) => { // منطق للتحقق من المسار (Route) الحالي const currentRoute = getCurrentRoute(); // منطق مخصص const senderId = notification.request.content.data.senderId; if (currentRoute === 'Chat' && activeConversationId === senderId) { return { shouldShowAlert: false, shouldPlaySound: true }; } return { shouldShowAlert: true, shouldPlaySound: true }; }, });
التحدي الخاص بك
قم بتحديث setNotificationHandler الخاص بك ليظهر البانرات فقط إذا كان طول نص الإشعار (body) أكبر من 10 أحرف. أرسل إشعارين تجريبيين عبر زر "الاختبار الفوري" — أحدهما قصير والآخر طويل — ولاحظ الفرق في السلوك.