فرض تذييل التنقل مع ملف تعريف الارتباط

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

تطبيق iOS المُنشأ باستخدام PWABuilder (بدون شريط تنقل سفلي):

ومع ذلك، يوجد شريط سفلي في تطبيق الويب التقدمي (PWA) على iOS يحتوي على زر رجوع. لكنني لم أجد طريقة لعرض هذا الشريط خارج نطاق تطبيق الويب التقدمي على iOS حتى الآن.

يحتوي تطبيق الويب التقدمي على iOS على شريط تنقل سفلي، لكن لا يمكن إجباره على الظهور خارج التطبيق (لم أجد طريقة سهلة):

والآن، سؤالي هو: هل يمكن عرض هذا الشريط السفلي أيضًا داخل WKWebView؟ لدي أيضًا فكرة حول كيفية حل هذه المشكلة. التطبيقات المُنشأة باستخدام PWABuilder تملك وظيفة تسمح بتعيين ملف تعريف ارتباط (cookie) عند الاستخدام. ماذا لو قمنا بعرض شريط التنقل السفلي كلما كان لدى المستخدم ملف تعريف ارتباط مثل “mobile_footer_nav”؟ عندها سيتم حل المشكلة.

الإعدادات التي يمكن تعيينها داخل تطبيق مُنشأ باستخدام PWABuilder (ملف تعريف ارتباط عند استخدام التطبيق)

سأكون ممتنًا جدًا لو أن فريق التطوير اطلع على هذا الأمر.

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

إعجاب واحد (1)

يقوم Discourse بتصيير التذييل بناءً على بعض الشروط. يُضاف التذييل هنا.

https://github.com/discourse/discourse/blob/a0bbc346cb5d5b89d1a3efdfa89869349a8b067f/app/assets/javascripts/discourse/app/templates/application.hbs#L39-L41

يُعرَّف showFooterNav هنا.

discourse/app/assets/javascripts/discourse/app/controllers/application.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub

إذا كان أي من الشرطين صحيحًا، فسيتم عرض شريط التنقل.

يُعرَّف isiOSPWA() و isAppWebview() هنا

discourse/app/assets/javascripts/discourse/app/lib/utilities.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub

على سبيل المثال، يبدو isAppWebview() كالتالي.

discourse/app/assets/javascripts/discourse/app/lib/utilities.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub

يمكنك إنشاء شرط إضافي في نسختك من الموضوع - في موقع Discourse - للتحقق من ملف تعريف الارتباط (cookie)، على النحو التالي

const isWKWebView = () => {
  // تحقق من ملف تعريف الارتباط وأرجع true إذا كان موجودًا
  // أو استخدم أي طريقة أخرى للكشف عما إذا كان المستخدم يستخدم تطبيقك
}

بالنسبة للفئات الأخرى، ستتمكن عادةً من تعديل showFooterNav() على النحو التالي

api.modifyClass("controller:application", {
  pluginId: "show-footer-nav",
  @discourseComputed
  showFooterNav() {
    // ...
  }
});

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

ومع ذلك، لا يزال بإمكانك تغيير قيمة showFooterNav باستخدام شيء مثل هذا.

<script type="text/discourse-plugin" version="0.8">
  const isWKWebView = () => {
    // تحقق وأرجع شرطك
  };

  if (isWKWebView()) {
    const applicationController = api.container.lookup("controller:application");
    applicationController.set("showFooterNav", true);
  }
</script>

في علامة التبويب رأس الصفحة (header) في نسختك من الموضوع أو في برنامج تهيئة أولية إذا كنت تستخدم موضوعًا عن بُعد.

5 إعجابات

شكرًا جزيلاً لك على المساعدة السريعة. للأسف، أواجه خطأً.

لقد كتبت هذه الأسطر من الكود في رأس السمة، وأضفت أيضًا إمكانية فحص ملفات تعريف الارتباط (cookies) داخل دالة isWKWebView(). إذا لم يكن لدي ملف تعريف ارتباط، فلا يحدث شيء. هذا يعمل حاليًا. ولكن إذا كان لدي ملف تعريف ارتباط، فلا يتم عرض هذا الشريط للأسف، ويظهر خطأ في وحدة التحكم (console) يقول: “TypeError: Attempted to assign to readonly property.”.

إعجاب واحد (1)

لقد جربت ذلك محليًا فقط، لذا ربما يكون هذا هو السبب.

جرب استخدام

applicationController.set("showFooterNav", true);

بدلاً من

applicationController.showFooterNav = true;

سأقوم بتعديل المنشور مع هذا التغيير.

إعجابَين (2)

يعمل بشكل مثالي! شكرًا جزيلاً :slight_smile:

الكود النهائي الخاص بي:

<script type="text/discourse-plugin" version="0.8">
function getCookie(cname) {
  let name = cname + "=";
  let decodedCookie = decodeURIComponent(document.cookie);
  let ca = decodedCookie.split(';');
  for(let i = 0; i < ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

if (getCookie("app-platform") != "") {
    const applicationController = api.container.lookup("controller:application");
    applicationController.set("showFooterNav", true);
}
</script>
إعجابَين (2)