تطبيقات الجوال ·

كود Flutter واحد لثلاث دول: كيف بنينا تطبيق Klik من كلام للجوال والويب

بوابة عملاء Klik من كلام على الويب وأمامها تطبيق Klik للجوال

تخدم شركة كلام للاتصالات عملاء الأعمال في البحرين والمملكة العربية السعودية والكويت. ولكل سوق نظامه الخاص، وكل منها يحتاج إلى تطبيق جوال. وبدلًا من بناء ثلاثة تطبيقات وصيانتها، بنينا Klik من كلام: كود Flutter واحد يعمل كتطبيق iOS وAndroid في الدول الثلاث، ويعمل أيضًا — بعد جولة من التحسين — كبوابة على الويب.

نستعرض في هذا المقال كيف نظّمنا المشروع، والتحديات التي واجهناها، خصوصًا على الويب.

ماذا يقدّم Klik

‏Klik هي منصة الخدمة الذاتية من كلام لعملاء الأعمال. يسجّل العملاء الدخول ليطّلعوا على المبالغ المستحقة ويسددوها بنقرة واحدة، ويتصفحوا المنتجات ويطلبوها، ويتابعوا طلباتهم، ويفتحوا تذاكر الدعم، ويديروا مستخدمي فريقهم، ويضبطوا إعدادات الإشعارات. ويعمل كل ذلك بالعربية والإنجليزية مع دعم كامل للكتابة من اليمين إلى اليسار، إضافة إلى المساعدة الذكية «هلا» داخل التطبيق.

الشاشة الرئيسية لتطبيق Klik على الجوال وتظهر فيها المبالغ المستحقة وزر الدفع السريع والخدمات السريعة
تطبيق Klik على الجوال: الرصيد المستحق والدفع السريع والخدمات السريعة في الشاشة الرئيسية.

كود واحد لثلاثة أنظمة

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

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

والنتيجة فريق واحد وكود واحد ومجموعة اختبارات واحدة، بدلًا من ثلاثة تطبيقات يبتعد كل منها عن الآخر مع الوقت.

كود واحد مقابل تطبيقات منفصلة

كان المسار التقليدي يعني تطبيق iOS أصليًا (Swift) وتطبيق Android أصليًا (Kotlin) وبوابة ويب منفصلة — لكل دولة من الدول الثلاث. أي ما يصل إلى تسعة أكواد منفصلة. وإليك مقارنة بين النهجين.

تطبيقات منفصلة لكل منصة ودولةكود Flutter واحد (Klik)
التكلفة
عدد الأكواد التي يجب بناؤها وصيانتهاحتى 9 (3 منصات × 3 دول)1
بناء ميزة جديدةتُبنى ويُدفع ثمنها مرة لكل منصة، ثم تُعدَّل لكل دولةتُبنى مرة واحدة وتُفعَّل لكل دولة عبر الإعدادات
الفريقمتخصصون في iOS وAndroid والويب، وغالبًا فريق لكل منصةفريق Flutter واحد
إصلاح خلليُكتشف ويُصلَح في كل تطبيق على حدةيُصلَح مرة واحدة في كل مكان
الاختبارمجموعة اختبارات ودورة ضمان جودة لكل تطبيقمجموعة اختبارات مشتركة، مع فحوصات لكل منصة
الصيانة على المدى الطويلتتضاعف مع كل تطبيق: ترقيات المكتبات وتحديثات أنظمة التشغيل والإصلاحات الأمنية × 9تتم مرة واحدة للمنصة بأكملها
الجانب التقني
الاتساقتبتعد التطبيقات تدريجيًا عن بعضها في الميزات والسلوكالشاشات والمنطق والسلوك نفسها في كل دولة وعلى كل جهاز
منطق العمليُعاد كتابته بكل لغة، مع خطر اختلاف النتائجيُكتب مرة واحدة بلغة Dart ويُشارَك
العربية والكتابة من اليمين إلى اليسارتُنفَّذ وتُختبر في كل تطبيقمبنية مرة واحدة في نظام التصميم المشترك
الأداءأصليقريب من الأصلي على الجوال، وتحميل أول أثقل على الويب
ميزات الجهاز الأصليةوصول مباشرعبر الإضافات (plugins)، مع الحاجة إلى نسخة ويب لبعضها (مثل الدفع)
الأعمال
سرعة الإطلاقتنتظر الإصدارات أبطأ منصةإصدار واحد يصل إلى جميع الأسواق والمنصات معًا
إضافة دولة جديدةأقرب إلى مشروع جديدفي الغالب إعدادات جديدة وربط بنظام خلفي جديد
تجربة العملاءقد تختلف بين التطبيق والويب، وبين الدولتجربة Klik نفسها في كل مكان

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

نقل التطبيق إلى الويب

ولأن Flutter يدعم الويب أيضًا، فإن الكود نفسه يشغّل بوابة العملاء على klik-bh.com. فيحصل العملاء على لوحة التحكم نفسها والخطوات نفسها والشكل نفسه على الحاسوب كما على الجوال.

لوحة تحكم عملاء Klik من كلام على الويب، وتظهر فيها الطلبات والخطوط والطلبات المعلقة والمنتجات
كود Flutter نفسه يعمل كبوابة Klik على الويب.

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

1. توقّف الدفع عبر CrediMax في المتصفح

على الجوال، يفتح Klik صفحة الدفع المستضافة من CrediMax داخل WebView. ويراقب التطبيق التنقّل داخلها، فيعرف لحظة عودة العميل من صفحة الدفع ويعرض النتيجة.

أما على الويب، فلا يوجد WebView أصلي في Flutter، لذلك تتحوّل الأداة نفسها إلى iframe. وقد عطّل ذلك عملية الدفع بطريقتين:

  • كثيرًا ما ترفض صفحات الدفع وصفحات التحقق المصرفي 3-D Secure العمل داخل iframe من موقع آخر، حمايةً من هجمات انتحال النقرات (clickjacking).
  • وحتى عندما تعمل الصفحة، لا يسمح المتصفح لتطبيقنا بقراءة عنوان صفحة من نطاق آخر داخل الـ iframe، فلم يعد التطبيق قادرًا على معرفة انتهاء عملية الدفع.

وكان الحل مسار دفع خاصًا بالويب. فعلى الويب، يوجّه Klik العميل إلى صفحة الدفع من CrediMax في المتصفح نفسه، وعند الانتهاء تعيده CrediMax إلى صفحة على klik-bh.com، ويتحقق التطبيق من حالة الدفع مع الخادم قبل عرض النتيجة. وتبقى تطبيقات الجوال على WebView داخل التطبيق. ويتشارك المساران منطق الطلبات والدفع نفسه، ويختلف فقط الجزء الذي يعرض صفحة الدفع.

2. حجم التحميل

يحمّل تطبيق Flutter على الويب محرّك العرض إلى جانب التطبيق نفسه، لذا يكون التحميل الأول أثقل بكثير من موقع عادي. ولأن العملاء يستخدمون البوابة أثناء تنقّلهم، ركّزنا على جعل التحميل الأول أخف ما يمكن:

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

واليوم يبلغ حجم ملف التطبيق الرئيسي 7.8 ميغابايت، لكنه ينتقل عبر الشبكة مضغوطًا بحجم 2.2 ميغابايت تقريبًا، ويُخزَّن مؤقتًا بعد الزيارة الأولى.

3. ميزات الجوال على الويب

بعض حزم Flutter تعمل على iOS وAndroid فقط. ولكل منها — مثل WebView الدفع المذكور أعلاه — كتبنا نسخة للويب خلف الواجهة البرمجية نفسها، فلا تحتاج الشاشات التي تستخدمها إلى معرفة المنصة التي تعمل عليها. وتأكدنا كذلك من أن سلوك المتصفح يعمل كما يتوقع المستخدمون، مثل زر الرجوع والروابط التي تفتح صفحة محددة.

ما تعلمناه

  • الكود الواحد يؤتي ثماره سريعًا. ثلاث دول وثلاث منصات تحصل على كل تحسين في آن واحد.
  • خطّط لنسخة الويب من اليوم الأول. الدفع والتعامل مع الملفات وكل ما يعتمد على مكوّن أصلي يحتاج إلى نسخة للويب.
  • تعامل مع صفحات الدفع كحالة خاصة. افترض أن بوابة الدفع لن تعمل داخل iframe، وتحقق دائمًا من حالة الدفع على الخادم.
  • راقب حجم التحميل مبكرًا. الحفاظ على صغر حجم نسخة Flutter للويب أسهل بكثير من تقليصه لاحقًا.

تخطط لتطبيق جوال؟

تبني Script Solutions تطبيقات الجوال وحلول الدفع الإلكتروني للشركات في البحرين ودول الخليج. اقرأ المزيد عن مشروع كلام للاتصالات، أو تواصل معنا للحديث عن مشروعك.

لديك مشروع في ذهنك؟

حدّثنا عن مشروعك، وسنعود إليك بخطة واضحة وجدول زمني وتقدير للتكلفة.