إشعارات iOS قد تفقد إذن الدفع إذا كان المستخدم نشطًا حاليًا

يمكن أن تفقد إشعارات iOS الإذن بالإرسال إذا تم كتم الإشعار. تمت تهيئة رمز Discourse لكتم الإشعارات اختياريًا، وبالتالي سيفقد الإذن بالإرسال عند حدوث ذلك ثلاث مرات.

إليك الرمز الخاص بعامل خدمة الإشعارات الفورية.

يحتوي هذا الرمز على خطأ فادح فيه، في السطر 178. هناك، يتحقق عامل الخدمة مما إذا كان المستخدم نشطًا (أي ليس خاملاً). في هذه الحالة، يعيد حدث الدفع قيمة false دون عرض إشعار.

(كما يتحقق من payload.hide_when_active، ولكن تبين أن hide_when_active هو دائمًا صحيح، وبالتالي يعيد هذا الرمز دائمًا قيمة false عندما يكون المستخدم نشطًا.)

تمنع Apple عمليات الدفع الصامتة، وتسحب إذن الدفع بعد ثلاث أحداث لا تعرض إشعارات

هذا غير مقبول بموجب قواعد Apple للإشعارات الفورية.

https://webkit.org/blog/12945/meet-web-push/

الطاقة والخصوصية

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

واجهة برمجة تطبيقات Web Push ليست دعوة لتشغيل وقت تشغيل الخلفية الصامت، لأن ذلك من شأنه أن ينتهك ثقة المستخدم ويؤثر على عمر بطارية المستخدم.

سيؤدي انتهاك وعد userVisibleOnly إلى إلغاء اشتراك الدفع.

(التأكيد لي)

تم شرح ذلك بمزيد من التفصيل في فيديو WWDC الخاص بـ Apple حول Web Pushes، في الدقيقة 9:57

https://developer.apple.com/videos/play/wwdc2022/10098/?time=596

لاحظ أننا نذكر صراحةً أننا نعد دائمًا بجعل عمليات الدفع مرئية للمستخدم. بينما تستوعب معايير واجهة برمجة تطبيقات JavaScript Push اختياريًا تشغيل وقت تشغيل الخلفية الصامت استجابةً لعملية دفع، فإن معظم المتصفحات لا تدعم ذلك. Safari لا تدعم ذلك.

… ثم في الدقيقة 13:35:

https://developer.apple.com/videos/play/wwdc2022/10098/?time=814

كما ذكرت عندما أريتك الرمز الخاص بكيفية طلب اشتراك الدفع، يجب أن تعد بأن عمليات الدفع ستكون مرئية للمستخدم. التعامل مع حدث الدفع ليس دعوة لبرنامج JavaScript الخاص بك للحصول على تشغيل وقت تشغيل الخلفية الصامت. القيام بذلك من شأنه أن ينتهك ثقة المستخدم وعمر بطارية المستخدم. عند التعامل مع حدث الدفع، يجب عليك في الواقع نشر إشعار في مركز الإشعارات. تمتلك المتصفحات الأخرى جميع الإجراءات المضادة ضد انتهاك الوعد بجعل عمليات الدفع مرئية للمستخدم، وكذلك Safari. في الإصدار التجريبي من macOS Ventura، بعد ثلاث أحداث دفع تفشل فيها في نشر إشعار في الوقت المناسب، سيتم إلغاء اشتراك الدفع الخاص بموقعك. ستحتاج إلى المرور عبر سير عمل الإذن مرة أخرى.

(التأكيد لي)

توصي Apple بعرض الإشعارات فورًا، وليس بعد إغلاق الإشعارات

يبدو الرمز الموصى به من Apple كما يلي، في الدقيقة 11:39:

https://developer.apple.com/videos/play/wwdc2022/10098/?time=699

self.addEventListener('push', (event) => {
    let pushMessageJSON = event.data.json();

    // يضع خادمنا كل ما هو ضروري لعرض الإشعار
    // في بيانات JSON الخاصة بنا.
    event.waitUntil(self.registration.showNotification(pushMessageJSON.title, {
        body: pushMessageJSON.body,
        tag: pushMessageJSON.tag,
        actions: [{
            action: pushMessageJSON.actionURL,
            title: pushMessageJSON.actionTitle,
        }]
    }));
}

تذكر كيف وعد برنامج JavaScript الخاص بنا، عندما اشتركنا في الدفع، بأنها ستكون دائمًا مرئية للمستخدم؟ هذا يعني أنه يجب علينا دائمًا عرض إشعار أصلي للمنصة استجابةً لكل عملية دفع. من الأفضل القيام بذلك في أقرب وقت ممكن في معالج حدث الدفع الخاص بك.

لا يتبع رمز Discourse أفضل الممارسات الموصى بها. يقوم رمز Discourse أولاً بإغلاق جميع الإشعارات، ثم يعرض إشعارًا.

يجب على Discourse دائمًا استدعاء showNotification استجابةً لحدث الدفع، ويجب عليه دائمًا القيام بذلك في أقرب وقت ممكن.

8 إعجابات

@Falco / @featheredtoast ما رأيك في هذا؟

ما هو تأثير إزالة كل من فحص الإغلاق والخمول؟

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

أسوأ سيناريو إذا تطلبنا هذا على Android أو Desktop (غير Safari) يمكننا دائمًا إضافة شرط هنا، ولكن شعوري هنا هو أنه يجب علينا فقط إزالة الكود هنا.

تصحيح ممتاز للأخطاء @dfabulich :hugs:

3 إعجابات

حسنًا، أفهم أنه لا بأس في تنفيذ الإغلاق، على ما أعتقد، طالما تم بعد استدعاء showNotification.

… لكنني بصراحة لا أرى أي فائدة من إغلاق الإشعارات على الإطلاق. من الأفضل تركها تتراكم في درج الإشعارات، في رأيي.

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

3 إعجابات

من ما قرأته في هذا الموضوع خلال عطلة نهاية الأسبوع، لا يمكننا حتى استخدام async/promises في معالج حدث الدفع، يجب أن نعرضه في أسرع وقت ممكن وإلا ستقوم Apple بإلغاء حقوق الإشعارات الخاصة بك.

كل هذا يتوافق مع ما يقوله @dfabulich.

أعتقد أننا نكون “أذكى” من اللازم، يجب علينا بالفعل إزالة جميع عمليات التحقق وعرض الإشعار فقط.

6 إعجابات

لا يمكنني شكرك بما فيه الكفاية يا @dfabulich لاكتشاف هذا!

3 إعجابات

حسنًا، لدي طلب سحب (PR) لهذا.
@Falco / @featheredtoast هل يجب علينا دمجه؟

إذا احتجنا إلى تخطي إشعارات الدفع، فيجب علينا القيام بذلك على الخادم وليس على العميل. كان منطق الانهيار دائمًا موضع تساؤل إلى حد ما، والتطبيقات لا تميل إلى القيام بذلك.

إعجابَين (2)

نعم، هذا منطقي أكثر بكثير لإرسال الإشعارات فقط عندما تحتاج إلى عرضها. يجب أن يؤدي ذلك إلى تقليل الإشعارات المفرطة في أماكن أخرى في المستقبل القريب، ولكني راضٍ عن دمج هذا هنا :+1:

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

إعجابَين (2)