Notification Service Extension: ما هو، معالجة المحتوى قبل العرض على iOS

المؤلف: IT Sectr نُشر: 2026-03-21 وقت القراءة: 8 دق

Notification Service Extension هو امتداد لنظام iOS يعترض الإشعار الفوري قبل عرضه للمستخدم ويسمح بتعديل المحتوى. يمكن للامتداد فك تشفير البيانات المشفرة، تنزيل المرفقات الوسائطية، تغيير النص، أو إضافة حقول مخصصة. وفقًا لـ Apple Developer, 2025، Notification Service Extension لديه حتى 30 ثانية لإكمال المهمة في الخلفية.

النقاط الرئيسية

  • Notification Service Extension هو امتداد iOS لمعالجة الإشعارات الفورية قبل العرض.
  • الامتداد يرث من UNNotificationServiceExtension ويطبق طريقة didReceive.
  • حتى 30 ثانية من التنفيذ في الخلفية لتنزيل ومعالجة البيانات.
  • حالات الاستخدام الرئيسية: فك تشفير الحمولة، تنزيل الصور والفيديو، التحقق من صحة المحتوى.
  • يمكن للامتداد تأخير عرض الإشعار أو إلغائه بالكامل عبر contentHandler.

ما هو Notification Service Extension

Notification Service Extension هو امتداد تطبيق في iOS يعمل قبل عرض الإشعار الفوري. يسمح للخادم بإرسال حمولة صغيرة بينما يقوم الامتداد بإثرائها بالمحتوى: تنزيل الصور، فك تشفير البيانات، استبدال النص. يرى المستخدم الإشعار المُعالَج بالفعل.

كيف يعمل

عندما يستقبل iOS إشعارًا فوريًا، يتحقق النظام من وجود امتداد للتطبيق. إذا كان الامتداد مسجلاً، يبدأه iOS في عملية خلفية ويمرر محتوى الإشعار عبر طريقة didReceive(_:withContentHandler:). يعالج الامتداد المحتوى ويستدعي contentHandler بالمحتوى المعدل. إذا لم يكتمل الامتداد خلال 30 ثانية، يعرض النظام الإشعار الأصلي.

متى تستخدم Service Extension

يكون Service Extension ضروريًا في السيناريوهات التي يتطلب فيها محتوى الإشعار معالجة على الجهاز. الاتصالات الآمنة: يرسل الخادم حمولة مشفرة، يقوم الامتداد بفك تشفيرها محليًا. الإشعارات الوسائطية الغنية: يرسل الخادم رابط صورة، يقوم الامتداد بتنزيلها وإرفاقها. التوطين الديناميكي: يقوم الامتداد باستبدال النص بلغة الجهاز.

السيناريوبدون امتدادمع الامتداد
صورةغير مدعومةيتم تنزيلها وعرضها
تشفيرالخادم يحتفظ بالمفتاحفك التشفير على الجهاز
نصمحدد مسبقًا على الخادماستبدال ديناميكي
تحققلا يتم التحققإلغاء الإشعارات الضارة

القيود ووقت التنفيذ

يعمل Notification Service Extension في بيئة محدودة. أقصى وقت للتنفيذ هو 30 ثانية. لا يمكن للامتداد الوصول إلى التخزين الرئيسي للتطبيق (باستثناء App Group). حجم الامتداد محدود بـ 50 ميجابايت. عند تجاوز الوقت، يستدعي النظام contentHandler بالمحتوى الأصلي وتفقد جميع التغييرات.

إنشاء الامتداد وتكوين Info.plist

في Xcode، يتم إضافة Notification Service Extension عن طريق إنشاء target جديد من نوع Notification Service Extension. يقوم Xcode بإنشاء فئة قالب NotificationService التي ترث من UNNotificationServiceExtension، بطريقتين: didReceive و serviceExtensionTimeWillExpire.

إضافة target إلى المشروع

في Xcode، اختر File → New → Target → Notification Service Extension. أدخل اسمًا (مثل PushNotificationService) واختر لغة Swift. تأكد من إضافة target إلى التطبيق الرئيسي ومن وجود التوقيع الصحيح. بعد الإنشاء، سيتم إنشاء فئة NotificationService.swift مع تنفيذ أساسي.

هيكل Info.plist للامتداد

يحتوي Info.plist للامتداد على مفتاح NSExtension مع المفاتيح الفرعية NSExtensionPointIdentifier (com.apple.usernotifications.service) و NSExtensionPrincipalClass (اسم وحدة التحكم الخاصة بك). بالإضافة إلى ذلك، يمكن تحديد NSExtensionAttributes مع قواعد تنشيط الامتداد. يقوم Xcode بإنشاء هذه الإعدادات تلقائيًا.

مثال امتداد أساسي

التنفيذ الأساسي يعيد تعريف didReceive، ويعدل محتوى الإشعار، ويستدعي contentHandler. إذا استغرقت المعالجة وقتًا طويلاً، يتم استدعاء serviceExtensionTimeWillExpire، حيث يجب إكمال العمل بالحالة الحالية.

swift
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(
        request: UNNotificationRequest,
        withContentHandler handler: @escaping (UNNotificationContent) -> Void
    ) {
        contentHandler = handler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            bestAttemptContent.title = "[تمت المعالجة] \(bestAttemptContent.title)"
            contentHandler?(bestAttemptContent)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler,
           let bestAttemptContent = bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

فك تشفير الحمولة المشفرة

أحد الاستخدامات الرئيسية لـ Service Extension هو فك تشفير محتوى الإشعار على الجهاز. يرسل الخادم حمولة مشفرة ويقوم الامتداد بفك تشفيرها باستخدام مفتاح مخزن في Keychain أو App Group. يضمن ذلك عدم إمكانية اعتراض المحتوى أثناء النقل.

بنية التسليم الآمن

يقوم الخادم بتشفير نص الإشعار باستخدام مفتاح متماثل (AES-256). يتم الاتفاق على مفتاح التشفير مسبقًا بين العميل والخادم. يستقبل الامتداد السلسلة المشفرة في حقل data من الحمولة، ويفك تشفيرها، ويستبدلها في حقول الإشعار. مفتاح المستخدم يمكن الحصول عليه من Keychain بعد المصادقة.

swift
override func didReceive(
    request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
    guard let content = request.content.mutableCopy()
        as? UNMutableNotificationContent else {
        handler(request.content)
        return
    }

    guard let encryptedData = content.userInfo["encrypted_data"]
        as? String else {
        handler(content)
        return
    }

    let decrypted = CryptoService.decrypt(encryptedData)
    content.body = decrypted.body
    content.title = decrypted.title
    handler(content)
}

تخزين المفاتيح الآمن

لا يجب تخزين مفتاح فك التشفير في كود الامتداد أو NSUserDefaults. استخدم iOS Keychain مع الوصول عبر App Group لكي يتمكن كل من التطبيق والامتداد من قراءة المفتاح. استخدم Security.framework مع خوارزمية AES-256-GCM لتوليد المفاتيح على العميل.

تنزيل وإرفاق المرفقات الوسائطية

الاستخدام الأكثر شيوعًا لـ Notification Service Extension هو تنزيل الصور وملفات GIF والفيديو لعرضها في الإشعار. يرسل الخادم رابط ملف وسائطي ويقوم الامتداد بتنزيله وحفظه في دليل مؤقت وإنشاء UNNotificationAttachment.

عملية تنزيل وإرفاق الوسائط

يستقبل الامتداد رابط الصورة من حقل payload في الإشعار. باستخدام URLSession، يقوم الامتداد بتنزيل الملف إلى دليل مؤقت. بعد اكتمال التنزيل، يتم إنشاء UNNotificationAttachment مع الرابط المحلي. يتم تمرير المرفق إلى المحتوى المعدل. iOS تلقائيًا يعرض الصورة في الواجهة القياسية أو في Notification Content Extension.

swift
private func downloadAndAttachMedia(
    content: UNMutableNotificationContent,
    mediaUrl: String,
    handler: @escaping (UNNotificationContent) -> Void
) {
    guard let url = URL(string: mediaUrl) else {
        handler(content)
        return
    }

    let task = URLSession.shared.downloadTask(with: url) { localUrl, _, error in
        guard let localUrl = localUrl, error == nil else {
            handler(content)
            return
        }

        let attachment = try? UNNotificationAttachment(
            identifier: "media",
            url: localUrl,
            options: nil
        )

        if let attachment = attachment {
            content.attachments = [attachment]
        }
        handler(content)
    }
    task.resume()
}

صيغ الوسائط المدعومة

يدعم iOS الصيغ التالية للعرض في الإشعارات: JPEG، PNG، GIF (ثابتة)، فيديو MPEG-4 حتى 50 ميجابايت. للملفات الصوتية، يتم دعم MP3 و AAC و ALAC. مهم: يجب تنزيل جميع الملفات الوسائطية في غضون 30 ثانية. للملفات الكبيرة، يُوصى بالقص على الخادم أو التحميل التدريجي.

إدارة الوقت وسيناريوهات الاحتياط

إدارة حد 30 ثانية هي مهمة رئيسية عند تطوير Notification Service Extension. إذا لم يكمل الامتداد المعالجة في الوقت المحدد، يستدعي النظام serviceExtensionTimeWillExpire ويعرض المحتوى الأصلي. يجب توفير سيناريوهات احتياط لكل نوع من أنواع المعالجة.

استراتيجية الأولويات

قم بتقسيم المهام حسب الأولوية. نفذ التعديلات الحرجة (فك التشفير، التوطين الأساسي) أولاً. التحسينات الاختيارية (تنزيل الصور، إثراء النص) تأتي ثانيًا. استخدم URLSession مع مهلة للطلبات الشبكية لتجنب إنفاق الحد بأكمله على عملية واحدة.

الاحتياط عند الأخطاء

إذا فشل تنزيل الصورة أو أعاد فك تشفير الحمولة خطأ، يجب على الامتداد استدعاء contentHandler بالمحتوى الأصلي. لا تنهي الامتداد أبدًا دون استدعاء contentHandler — فهذا يؤدي إلى فقدان الإشعار. الاحتياط الآمن يجب دائمًا تضمينه في كود الامتداد.

swift
override func didReceive(
    request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
    let content = (request.content.mutableCopy()
        as? UNMutableNotificationContent) ?? request.content

    // مهمة حرجة: فك التشفير
    var decryptedContent = tryDecryptPayload(content)

    // مهمة اختيارية: الوسائط
    guard let mediaUrl = decryptedContent.userInfo["media_url"]
        as? String else {
        handler(decryptedContent)
        return
    }

    downloadAndAttachMedia(
        content: decryptedContent,
        mediaUrl: mediaUrl,
        handler: handler
    )
}

اختبار الامتداد

لاختبار Notification Service Extension، استخدم Xcode: حدد target الامتداد، شغله على المحاكي، وأرسل إشعارًا فوريًا عبر الطرفية أو Firebase Console. سجل كل مرحلة من مراحل المعالجة باستخدام os_log — يساعد ذلك في تشخيص مشكلات التوقيت والتنزيل.

الأسئلة الشائعة

ماذا يحدث إذا لم يكتمل الامتداد في غضون 30 ثانية؟

يستدعي النظام serviceExtensionTimeWillExpire، ثم يعرض الإشعار الأصلي دون تغييرات. يتم تجاهل جميع الملفات التي تم تنزيلها والتعديلات.

هل يمكن إلغاء عرض الإشعار من الامتداد؟

نعم، إذا استدعيت contentHandler بمحتوى فارغ (UNNotificationContent بحقول فارغة)، لن يتم عرض الإشعار. يُستخدم هذا لتصفية إشعارات السبام أو البيانات غير الصحيحة.

كيفية تمرير رمز التفويض لتنزيل الوسائط؟

يمكن تمرير الرمز في userInfo من payload الإشعار أو الحصول عليه من Keychain عبر App Group. لا يُوصى بتخزين الرموز في UserDefaults للامتداد.

هل يتطلب الامتداد تكوين شهادات خاص؟

يجب توقيع الامتداد بنفس شهادة المطور المستخدمة للتطبيق الرئيسي. للإنتاج، يلزم شهادة إنتاج مع تفعيل إمكانية Push Notifications.

كيفية تصحيح أخطاء الامتداد على جهاز حقيقي؟

قم بتوصيل الجهاز بـ Xcode، حدد target الامتداد في خطة التشغيل، وأرسل إشعارًا فوريًا عبر Firebase Console. نقاط التوقف في الامتداد تعمل بنفس الطريقة كما في التطبيق الرئيسي.

الملخص

  • Notification Service Extension هو امتداد iOS لمعالجة الإشعارات الفورية في الخلفية قبل العرض.
  • أقصى وقت للتنفيذ هو 30 ثانية، وبعدها يعرض النظام المحتوى الأصلي.
  • حالات الاستخدام الرئيسية: فك تشفير الحمولة، تنزيل الوسائط، التحقق من صحة المحتوى وتوطينه.
  • الامتداد يرث من UNNotificationServiceExtension مع طريقتي didReceive و serviceExtensionTimeWillExpire.
  • لتنزيل الوسائط استخدم URLSession، لتخزين المفاتيح استخدم iOS Keychain.
  • وفر دائمًا احتياطًا — استدعِ contentHandler بالمحتوى الأصلي عند الأخطاء.
  • ادمج Service Extension مع Content Extension للتحكم الكامل في الإشعارات.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا