إذا قمتم ببناء تطبيقكم مقابل SDK الخاص بنظام iOS 27 دون تبنّي دورة حياة UIScene، فلن يعمل التطبيق إطلاقاً. والتطبيق الذي لا يعمل لا يُسجَّل أبداً لتلقي الإشعارات الفورية (Push Notifications)، فتتوقف إشعاراتكم بصمت دون أي تقرير أعطال يشير إلى الإشعارات كسبب. العرض يبدو وكأنه مشكلة في التسليم، لكنه في الحقيقة مشكلة في تشغيل التطبيق.

هذا الخطأ يفاجئ الفرق تحديداً لأن الإشعارات وتشغيل التطبيق يبدوان أمرين منفصلين تماماً، سواء في الكود أو في تفكير المطورين. نظام iOS 27 يربط بينهما. يغطي هذا الدليل ما الذي يتعطل بالضبط، السلسلة الدقيقة التي تُسكت إشعاراتكم، من يقع ضمن نطاق التأثر، وقائمة الترحيل اللازمة لإصلاح المشكلة. Pushwoosh منصة لتفاعل العملاء، وحزمة تطوير iOS الخاصة بنا تتعامل بالفعل مع هذا الانتقال، لكن الحل أدناه ينطبق سواء كنتم تستخدمون منصتنا أم لا.

📖

هذا جزء من دليلنا الشامل لإصدار iOS 27. وبينما يجري العمل على تحديث الـ SDK، يستحق الأمر أيضاً التحقق من نطاق وصول أجهزتكم الفعلي.

ما الذي يتعطل فعلياً

أعلنت Apple في مؤتمر WWDC25 أن الإصدار الذي يلي iOS 26 سيفرض دورة حياة UIScene على أي تطبيق UIKit يُبنى باستخدام أحدث SDK. iOS 27 هو ذلك الإصدار، وهذا المتطلب مُفعّل الآن بالفعل.

المحفّز هنا هو الأهم، وأغلب النقاشات القلقة تخطئ في فهمه: يبدأ التطبيق الفعلي عندما تبنون تطبيقكم مقابل SDK الخاص بـ iOS 27 داخل Xcode 27، وليس فقط عندما يشغّل مستخدم تطبيقكم الحالي على جهاز يعمل بنظام iOS 27. النسخة المنشورة حالياً من تطبيقكم تستمر بالعمل على الأجهزة المُحدَّثة. المشكلة تحدث مع إصداركم التالي المبني على الـ SDK الجديد. هذا الفارق يمنحكم بعض الوقت، لكن فقط حتى موعد التسليم القادم.

أما ما لا يتغير، وهو ما تبالغ فيه أغلب المقالات المثيرة للقلق، فهو أن مسار APNs نفسه يبقى دون أي تعديل. لا تزالون تطلبون الإذن، وتستدعون registerForRemoteNotifications()، وتستقبلون رمز الجهاز في didRegisterForRemoteNotificationsWithDeviceToken كما كان الحال دائماً. هذه الدالة تبقى في AppDelegate، ولا يوجد حالياً في iOS 27 أي مكافئ قائم على scene يمكن نقلها إليه. آلية الإشعارات نفسها سليمة تماماً. ما غيّرته Apple هو عملية تشغيل التطبيق.

السلسلة التي تُسكت إشعاراتكم

عندما يُبنى تطبيق بدون scene manifest مقابل SDK الخاص بـ iOS 27، يحدث العطل وفق هذا الترتيب:

  1. يتحقق UIKit عند التشغيل من وجود scene ولا يجد أي UIApplicationSceneManifest في ملف Info.plist الخاص بكم.
  2. ينتهي التطبيق قبل تنفيذ أي دالة من دوال AppDelegate.
  3. بما أن application(_:didFinishLaunchingWithOptions:) لا تُنفَّذ أبداً، فإن registerForRemoteNotifications() لا تُستدعى أيضاً.
  4. دون تسجيل، لا تُستدعى didRegisterForRemoteNotificationsWithDeviceToken أبداً، فلا يتلقى التطبيق أي رمز APNs.
  5. لا رمز، لا تسليم. وبما أن التطبيق تعطّل عند التشغيل، تشير السجلات إلى مرحلة التشغيل وليس إلى مسار الإشعارات.

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

من يقع ضمن نطاق التأثر

يطال هذا المتطلب تطبيقات UIKit، لكن مدى تأثيره يعتمد على البنية التقنية المستخدمة لديكم.

البنية التقنيةدرجة التأثر
UIKit الأصليتأثير مباشر. إذا كنتم تملكون دورة حياة AppDelegate، فأنتم من يتولى الترحيل.
SwiftUIالمخاطرة أقل إذا كنتم تستخدمون بروتوكول App وWindowGroup، وهما مبنيان أصلاً على scene. أما التطبيقات التي لا تزال تعتمد على UIApplicationDelegateAdaptor مع منطق نافذة مخصص فتحتاج إلى مراجعة دقيقة.
Flutterيقوم الإطار البرمجي في الإصدارات الحديثة بترحيل التطبيقات ذات AppDelegate غير المعدّل تلقائياً، لكن أي منطق أصلي مخصص يجب ترحيله يدوياً.
React Nativeيعتمد على الوحدات الأصلية لديكم وأي طبقة SDK خارجية تتدخل في AppDelegate.
البنية التقنية
1 / 4
UIKit الأصلي
درجة التأثر
تأثير مباشر. إذا كنتم تملكون دورة حياة AppDelegate، فأنتم من يتولى الترحيل.
البنية التقنية
2 / 4
SwiftUI
درجة التأثر
المخاطرة أقل إذا كنتم تستخدمون بروتوكول App وWindowGroup، وهما مبنيان أصلاً على scene. أما التطبيقات التي لا تزال تعتمد على UIApplicationDelegateAdaptor مع منطق نافذة مخصص فتحتاج إلى مراجعة دقيقة.
البنية التقنية
3 / 4
Flutter
درجة التأثر
يقوم الإطار البرمجي في الإصدارات الحديثة بترحيل التطبيقات ذات AppDelegate غير المعدّل تلقائياً، لكن أي منطق أصلي مخصص يجب ترحيله يدوياً.
البنية التقنية
4 / 4
React Native
درجة التأثر
يعتمد على الوحدات الأصلية لديكم وأي طبقة SDK خارجية تتدخل في AppDelegate.

النقطة الحساسة بالنسبة لفرق العمل متعددة المنصات ليست الإطار البرمجي نفسه، بل الحزم البرمجية المُركَّبة فوقه. أي حزمة إشعارات أو تحليلات تُثبّت نفسها عبر تغليف AppDelegate الخاص بكم قد تعطّل ترحيل scene إلى أن يُصدر ذلك المزوّد دعمه الخاص. إذا كانت نقطة الدخول @main مملوكة لحزمة تابعة، فأنتم تنتظرون إصدارها هي، لا إصداركم فقط. رأينا ترحيلاً تعطّل لمدة أسبوعين تحديداً لهذا السبب — حزمة واحدة غير متعاونة، بينما كل ما كان الفريق يتحكم فيه فعلياً كان جاهزاً بالفعل. تحققوا من توافق حزمة الإشعارات لديكم مع scene قبل افتراض أن الترحيل مسألة يوم واحد. إذا كنتم تستخدمون إضافة Flutter الخاصة بنا، فصفحة المشكلات المعروفة في الترحيل هي أول ما يجب قراءته.

قائمة الترحيل

الحل لم يتغيّر منذ إدخال scene عام 2019. ما تغيّر هو أنه لم يعد اختيارياً.

  • أضيفوا scene manifest. ضعوا UIApplicationSceneManifest في ملف Info.plist، أو أعدّوا إعدادات scene برمجياً عبر دوال UIApplicationDelegate وUISceneDelegate.
  • أنشئوا SceneDelegate. إذا لم يكن لديكم واحد، أضيفوه وتأكدوا من أنه يُترجَم فعلياً ضمن target الخاص بكم. وجود SceneDelegate في المشروع دون إضافته إلى ملفات البناء فخّ شائع.
  • انقلوا إنشاء النافذة. تنتقل ملكية النافذة خارج AppDelegate. استبدلوا UIWindow(frame:) بـ UIWindow(windowScene:) واستضيفوا العرض الجذري من scene.
  • انقلوا معالجة دورة حياة الواجهة. تنتقل انتقالات المقدمة والخلفية والنشاط/عدم النشاط إلى UISceneDelegate. بعد الترحيل، يتوقف UIKit عن استدعاء دوال حالة الواجهة في AppDelegate، فما يبقى هناك يتوقف عن العمل بصمت.
  • أبقوا تسجيل الإشعارات في مكانه. يبقى تسجيل الرمز ودوال الاستجابة الخاصة به في AppDelegate. لا تنقلوها سعياً وراء التناظر.
  • رحّلوا معالجة الروابط والربط العميق. تصل الروابط الواردة الآن عبر دوال scene. إذا كانت إشعاراتكم تفتح شاشات محددة، فهذه الخطوة هي ما يبقي الروابط العميقة تعمل.
  • أعيدوا البناء وتحققوا من إصدار الرمز. ابنوا باستخدام SDK الخاص بـ iOS 27، وشغّلوا التطبيق، وتأكدوا من استلامه رمز APNs. إذا لم يستلمه، فدليل استكشاف أخطاء iOS وإصلاحها هو نقطة البداية المناسبة. تحققوا على نسخة فعلية قبل الإصدار، لا بعده.

أبقوا AppDelegate. هذه هي النقطة التي تخطئ فيها الفرق عادة عند قراءة أن “AppDelegate بصدد الاختفاء”. إنه لا يختفي. يضيق دوره ليقتصر على أحداث مستوى العملية والتطبيق، بينما تنتقل دورة حياة الواجهة إلى scene. تسجيل الإشعارات شأن على مستوى التطبيق، ولهذا السبب تحديداً يبقى في مكانه.

لماذا الاعتماد على الإشعارات وحدها أمر هشّ

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

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

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

👉🏻

وبينما العمل على الـ SDK لا يزال مستمراً، هذه فرصة جيدة أيضاً لمراجعة ما الذي يجعل إشعاراً ما جديراً بالإرسال.

اطلبوا من Pushwoosh مراجعة إعداد الإشعارات لديكم في iOS 27

تدعم حزمة Pushwoosh البرمجية بالفعل دورة حياة scene في iOS 27، ويعني إعدادها متعدد القنوات أن عطلاً في منصة واحدة لن يُسقط استراتيجية الإشعارات لديكم بالكامل معه. إذا كنتم في منتصف عملية الترحيل ولم يعمل التسجيل بشكل صحيح، فإن الأسئلة الشائعة لحزمة iOS تغطي أكثر المشكلات شيوعاً. وإذا أردتم رأياً مستقلاً حول ما إذا كان تسجيل الإشعارات لديكم سينجو من هذا التغيير، يمكننا مراجعة تكاملكم معكم — على بنية تحتية معتمدة وفق SOC 2 Type I وISO 27001:2022 ومتوافقة مع GDPR، مع مراكز بيانات في الاتحاد الأوروبي والولايات المتحدة.

راجعوا إعداد الإشعارات لديكم لنظام iOS 27
تحققوا من توافق iOS 27

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

ليس من تلقاء نفسه. التطبيق الموجود بالفعل على App Store يستمر بالعمل على أجهزة iOS 27. تحدث المشكلة عندما تبنون إصداراً جديداً مقابل SDK الخاص بـ iOS 27 دون تبنّي دورة حياة scene، وذلك الإصدار لن يعمل. نسخة تطبيقكم المنشورة حالياً آمنة حتى موعد التسليم القادم.

Pushwoosh Team
Content Team في Pushwoosh
مشاركة

مقالات ذات صلة

عرض الكل