إذا كنت مطور تطبيقات جوال ، فربما حلمت بمرونة التطوير عبر الإنترنت لإجراء تغييرات في التخطيط والمنطق أثناء التنقل والقدرة على إجراء اختبارات الفرضيات في ثوانٍ ونتائج المعالجة بشكل أسرع؟

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

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

ما هو التطوير المدفوع بالخلفية؟

التطوير المستند إلى الواجهة الخلفية (أو التطوير المستند إلى الواجهة الخلفية ، أو واجهة المستخدم المعتمدة على الواجهة الخلفية ، أو واجهة المستخدم المدفوعة بالخادم) هو مفهوم تطوير تطبيقات الواجهة الأمامية بناءً على استجابات الخادم. تتغير الشاشات والتدفق بناءً على استجابات الخادم.

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

النهج التقليدي لتطبيق الشاشات له عيوب معينة ، حيث يمكن أن يكون هناك الكثير من منطق الأعمال في جانب التطبيق ، ويصبح الحفاظ على الكود أكثر صعوبة:

  • تحتاج إلى نفس الرمز للعديد من الأنظمة الأساسية (Android و iOS والويب وما إلى ذلك). يجعل هذا النهج من الصعب الحفاظ على التوافق عبر الأنظمة الأساسية ، مما يزيد من فرصة الأخطاء وعدم التوافق ؛
  • يشير كل تحديث أو تعديل لتطبيق الهاتف المحمول إلى الحاجة إلى تغيير الرمز ، مما يؤدي إلى إصدار موسع للتطبيقات في متجر التطبيقات ؛
  • في النظام الرقمي ، يعد اختبار A / B أكثر صعوبة. يعتبر اختبار المفاهيم وجمع البيانات من المستخدمين لفهم معلومات المنتج المهمة أكثر صعوبة ؛
  • نظرًا لأن معظم منطق الأعمال موجود في جانب التطبيق ، فإن الحفاظ على الكود وصيانته أكثر صعوبة.

لقد وصلت التنمية الموجهة نحو الواجهة الخلفية لحل هذه المشاكل.

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

Scenario for backend driven development

 {
    "pageTitle" : "عنوان توضيحي" ،
    "مربعات" : [
        {
            "type ": "bigBlue" ،
            "العنوان" : "صندوق جميل" ،
            "العنوان الفرعي" : "العنوان الفرعي للمربع"
        } ،
        {
            "type ": "smallRed" ،
            "العنوان" : "Great Box"
        } ،
        {
            "النوع ": "المستطيل الأخضر" ،
            "العنوان" : "مربع لا تصدق" ،
            "العنوان الفرعي" : "العنوان الفرعي للمربع" ،
            "الرقم" : 10
        }
    ]
}

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

في المثال ، لعرض الكتل على الشاشة ("bigBlue" و "smallRed" و "rectangleGreen") ، يتم استخدام معلومات إضافية من كل حقل. ومن المثير للاهتمام أن متغير "المربعات" يسمح للواجهة الخلفية بمعالجة أكبر عدد ممكن من الكتل التي يقدمها الخادم.

هل خمنت بالفعل كيف يمكنك إجراء اختبار A / B في هذه الحالة؟ يمكن للخادم تحديد مستخدمين محددين لعرض كتل "bigBlue" فقط ، بينما يمكن للآخرين رؤية جميع أنواع الكتل الثلاثة. يمكنك أيضًا إجراء اختبارات A / B التي تغير ترتيب عرض الكتل على الشاشة.

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

Making changes to the interface in backend driven development

 {
    "pageTitle" : "عنوان توضيحي" ،
    "مربعات" : [
        {
            "النوع ": "المستطيل الأخضر" ،
            "العنوان" : "عنوان آخر" ،
            "العنوان الفرعي" : "عنوان فرعي آخر" ،
            "العدد" : 100
        } ،
        {
            "type ": "smallRed" ،
            "العنوان" : "عنوان مختلف"
        }
        {
            "type ": "bigBlue" ،
            "العنوان" : "الخلفية مدفوعة" ،
            "العنوان الفرعي" : "التنمية"
        }
    ]
}

فكر مرتين

هناك بعض الأشياء التي يجب وضعها في الاعتبار عند استخدام نهج التطوير المدفوع للخلفية. أولاً ، ما درجة المرونة التي تحتاجها؟

بناءً على الخبرة والأبحاث ، نعتبر أن المرونة المتوسطة هي الأمثل.

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

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

إنشاء تطبيق فائق ، Movile Tech Case

ربما تكون على دراية بمفهوم التطبيق الفائق وسمعت عن تطبيق مثل WeChat. WeChat هي عبارة عن منصة مراسلة عبر الهاتف المحمول وشبكة اجتماعية تم تطويرها في الصين وأصبحت تحظى بشعبية كبيرة في جميع أنحاء العالم.

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

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

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

أنشأ MovilePay شاشة رئيسية قائمة على الفئة لحل هذه المشكلة. يحتوي كل قسم على مجموعة عناصر خاصة به تسمى عناصر واجهة المستخدم. تعرض الأقسام نقاط الدخول لأي خدمات تم تنفيذها بالفعل بأي ترتيب وعناصر واجهة مستخدم فردية مميزة.

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

Widgets that the MovilePay application

Widgets in MovilePay application

Widgets in MovilePay application

Widgets in MovilePay application

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

Parsing and creating a home screen

 [
    {
        "العنوان" : "القسم 1" ،
        "الحاجيات" : [
            {
                "المعرف" : "COLLECTION_WIDGET" ،
                "المحتوى" : [
                    {
                        "العنوان" : "العنوان أ" ،
                        "صورة" : "أ" ،
                        "اللون" : "أصفر"
                    } ،
                    {
                        "العنوان" : "العنوان ب" ،
                        "صورة" : "ب" ،
                        "اللون" : "أزرق"
                    } ،
                    {
                        "العنوان" : "العنوان ج" ،
                        "صورة" : "C" ،
                        "اللون" : "أحمر"
                    } ،
                    {
                        "العنوان" : "العنوان د" ،
                        "صورة" : "D" ،
                        "اللون" : "أرجواني"
                    } ،
                    {
                        "العنوان" : "العنوان هـ" ،
                        "صورة" : "E" ،
                        "اللون" : "أخضر"
                    }
                ]
            } ،
            {
                "المعرف" : "IMAGES_WIDGET" ،
                "المحتوى" : [
                    {
                        "صورة" : "صورة" ،
                        "اللون" : "أخضر"
                    } ،
                    {
                        "صورة" : "صورة" ،
                        "اللون" : "أزرق"
                    } ،
                    {
                        "صورة" : "صورة" ،
                        "اللون" : "برتقالي"
                    }
                ]
            } ،
            {
                "المعرف" : "COLLECTION_WIDGET" ،
                "المحتوى" : [
                    {"العنوان" : "العنوان E" ، "الصورة" : "E" ، "اللون" : "الأخضر" } ، { "العنوان" : "العنوان F" ، "الصورة" : "F" ، "اللون" : "أرجواني " } ، { " title " : " Title G " ، " image " : " G " ، " color " : " red " } ، { " title " : " Title H " ، " image " : " H " ، " color " : " blue " } ، { " title " : " Title H " ، " image " : " H " ، " color " : " yellow " } ] } ] } ، { " title " : " Section 2 " ، " widgets " : [ { " المعرف " : " CELLS_WIDGET " ، " المحتوى " : [ { " العنوان " : " الخلية 1 " ، " اللون " : " أحمر " } ، { " العنوان " : " الخلية 2 " ، " اللون " : "أرجواني" } ، { "العنوان" : "الخلية 3" ، "اللون" : "أصفر" } ، { "العنوان" : "الخلية 4" ، "اللون" : "الأزرق" } ، { "العنوان" : "الخلية 5 " ، " color " : " dark green " } ] } ] } ]

سنستعرض أيضًا بعض الشاشات التي قد يتم إنشاؤها باستخدام التطوير المستند إلى الخلفية.

Home screens in backend-driven development

التنقل المرن

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

قررت MovilePay تطوير حزمة SDK للدفع بناءً على نموذج Google Pay أو Apple Pay أو VisaCheckout التي يمكن دمجها مع أي تطبيق آخر.

ومع ذلك ، نظرًا لأن العمل على SDK يتضمن قدرة قليلة جدًا على الاختبار باستخدام أنماط التطوير النموذجية ، فإن الأتمتة ضرورية.

نظرًا لأن MovilePay تعامل مع المدفوعات ، كان تحويل التدفقات أمرًا بالغ الأهمية. لا تستطيع MovilePay أن تفقد مستخدميها في أي مرحلة من مراحل مسار التحويل. لذلك ، كان تحسين العملية التجارية بأكملها ضروريًا - من تسجيل المستخدم إلى إضافة بطاقة والدفع. إنه المكان الذي أصبح فيه التطوير المستند إلى الواجهة الخلفية مفيدًا مرة أخرى ، مما يحول الخادم إلى "متصفح" التطبيق.

Optimizing the business process with BDD

لم تعرف أي من شاشات تطبيق MovilePay الشاشة التالية. بعد انتهاء الشاشة السابقة من مهامها ، كان الخادم مسؤولاً عن إعادة الشاشة التي يجب عرضها بعد ذلك.

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

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

مثال آخر هو كيفية استخدام MovilePay للتطوير المستند إلى الخلفية لحل مشاكله. نعتقد أنك عجائبكيفية تطبيق هذا النهج في الممارسة العملية. اسمحوا لي أن أريكم كم هو سهل.

هناك العديد من الطرق البديلة لتحقيق نفس الهدف. سنوضح لك كيف فعلت MovilePay ذلك لنظام iOS. إذا رغبت في ذلك ، يمكن تطبيق هذا المفهوم على أي منصة أمامية أخرى.

عندما نفذت MovilePay ذلك ، فقد أخذوا في الاعتبار متطلبات مثل سهولة إضافة عناصر واجهة مستخدم إضافية ، وقراءة الكود ، والمسؤولية الفردية. لجعل الأمور أبسط وأكثر أصالة ، قررت MovilePay استخدام Codable API للتسلسل.

الحاجيات (iOS)

فيما يتعلق بالمرونة ، شعرت MovilePay أن أفضل حل سيكون لتعميم عناصر واجهة المستخدم التي يجب تحليلها باستخدام بروتوكول. يعين MovilePay أيضًا تعدادًا لتحديد بنية عنصر واجهة المستخدم لتحليل البيانات.

 أداة البروتوكول : قابلة للفك { }

enum WidgetIdentifier : سلسلة ، قابلة للفك {
    بانر الحالة = "BANNER"
    مجموعة الحالة = "COLLECTION"
    قائمة الحالات = "LIST"

    var metatype : القطعة . اكتب {
        التبديل الذاتي {
        حالة . بانر :
            إرجاع BannerWidget . الذات
        حالة . المجموعة :
            عودة CollectionWidget . الذات
        حالة . قائمة :
            عودة ListWidget . الذات
        }
    }
}

إنهم يستفيدون من Codable API من خلال بروتوكول Decodable الذي ينفذه بروتوكول Widget. يوجد أدناه مثال على تحديد بنية عنصر واجهة المستخدم.

 هيكل BannerWidget : القطعة {
    دع خاص imageURLString : String
}

Struct CollectionWidget : القطعة {

    عنصر البنية : قابل للفك {
        دع imageURLString : String
        اسمحوا العنوان : سلسلة
        اسمحوا العنوان الفرعي : سلسلة
    }

    اسمحوا sectionTitle : String
    السماح بالقائمة : [ عنصر ]
}

هيكل ListWidget : القطعة {

    عنصر البنية : قابل للفك {
        دع imageURLString : String
        اسمح للنص : سلسلة
    }

    اسمحوا sectionTitle : String
    السماح بالقائمة : [ عنصر ]
}

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

 الفئة النهائية AnyWidget : قابلة للفك {

    مفاتيح ترميز التعداد الخاص : CodingKey {
        معرف الحالة
    }

    دعونا القطعة : القطعة ؟

    المطلوب init ( من وحدة فك الترميز : Decoder ) رميات {
        افعل _
            دع الحاوية = جرب وحدة فك التشفير . حاوية ( keyedBy : CodingKeys . self )
            دعونا اكتب = جرب الحاوية . فك الشفرة ( WidgetIdentifier . self ، forKey :. identifier )
            النفس . القطعة = حاول الكتابة . metatype . الحرف الأول ( من : مفكك الشفرة )
        } قبض {
            النفس . القطعة = لا شيء
        }
    }
}

يتم استخدام نوع المحو هذا لفك تشفير معرف عنصر واجهة المستخدم وخاصية "نوع التعريف" الخاصة به لتحديد هيكل عنصر واجهة المستخدم الذي يجب استخدامه لتحليل باقي بيانات عنصر واجهة المستخدم التي تم تحليلها.

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

 Struct HomeResponse : قابل للفك {

    مفاتيح ترميز التعداد الخاص : CodingKey {
        الحاجيات القضية
    }

    دع الحاجيات : [ القطعة ]

    init ( من وحدة فك الترميز : Decoder ) رميات {
        دع الحاوية = جرب وحدة فك التشفير . حاوية ( keyedBy : CodingKeys . self )
        النفس . الحاجيات = جرب الحاوية . فك ( [ AnyWidget ] . self ، forKey :. widgetsss = "علامات الترقيم المميزة">) . CompactMap {$ 0. widget } } init ( الحاجيات : [ Widget ] ) { self . الحاجيات = الحاجيات } }

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

يوجد أدناه استجابة محتملة لواجهة برمجة تطبيقات JSON والتي سيقوم هذا النموذج بتحليلها.

 {
    "الحاجيات" : [
        {
            "المعرف" : "BANNER" ،
            "imageURLString" : "url_image_to_be_downloaded"
        } ،
        {
            "المعرّف" : "COLLECTION" ،
            " عنوان القسم" : "عنوان القسم" ،
            "قائمة" : [
                {
                    "imageURLString" : "url_image_to_be_downloaded" ،
                    "العنوان" : "عنصر العنوان 1" ،
                    "العنوان الفرعي" : "عنصر الترجمة 1"
                } ،
                {
                    "imageURLString" : "url_image_to_be_downloaded" ،
                    "العنوان" : "عنصر العنوان 2" ،
                    "العنوان الفرعي" : "عنصر الترجمة 2"
                } ،
                {
                    "imageURLString" : "url_image_to_be_downloaded" ،
                    "العنوان" : "عنصر العنوان 3" ،
                    "العنوان الفرعي" : "عنصر الترجمة 3"
                }
            ]
        } ،
        {
            "المعرف" : "LIST" ،
            " عنوان القسم" : "عنوان القسم" ،
            "قائمة" : [
                {
                    "imageURLString" : "url_image_to_be_downloaded" ،
                    "نص" : "عنصر نص 1"
                } ،
                {
                    "imageURLString" : "url_image_to_be_downloaded" ،
                    "النص" : "عنصر النص 2"
                } ،
                {
                    "imageURLString" : "url_image_to_be_downloaded" ،
                    "نص" : "عنصر نص 3"
                }
            ]
        } ،
        {
            "المعرف" : "BANNER" ،
            "imageURLString" : "url_image_to_be_downloaded"
        }
    ]
}

هذا النهج قريب جدًا من تطوير التطبيق الفائق ، والذي سمح لـ MovilePay بتقديم خدمات مختلفة لمستخدمين مختلفين ، واختبار العديد من خيارات العرض ، ووضع الفرضيات ، وتحديد الأداة التي سيتم استخدامها لأي خدمة. كان التغيير في فرز الشاشة وتجميع الخدمات قريبًا مما فعله MovilePay من قبل.

التنقل (iOS)

بعد إصلاح مشكلة الأداة ، حاول MovilePay تحسين التنقل بالمثل. قاموا بإنشاء بروتوكول العمل ، والذي كان مطابقًا لبروتوكول القطعة.

الإجراء هو كائن منظم يتم إرجاعه في استجابة JSON لبعض واجهات برمجة تطبيقات MovilePay ، مع معرف وأي معلمات يجب عرضها في المشهد الذي يمثله. نتيجة لذلك ، يكون بروتوكول الإجراء مسؤولاً عن المساعدة في تفكيك الكائن المهيكل.

 إجراء البروتوكول : قابل للفك {
    مشهد func ( ) - > UIViewController
}

تعداد ActionIdentifier : سلسلة ، قابلة للفك {
    منزل الحالة = "HOME"
    شاشة حالة واحدة = "SCREEN_ONE"
    شاشة الحالة اثنان = "SCREEN_TWO"

    var metatype : الإجراء . اكتب {
        التبديل الذاتي {
        حالة . المنزل :
            العودة إلى HomeAction . الذات
        حالة . شاشة واحدةعامل التشغيل ">: إرجاع ScreenOneAction . self case . screenTwo : return ScreenTwoAction . self } } } view Raw

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

 هيكل HomeAction : Action {
    func scene ( ) - > UIViewController {
        عودة منسق المنزل . مشهد ( )
    }
}

هيكل ScreenOneAction : الإجراء {
    اسمحوا العنوان : سلسلة

    func scene ( ) - > UIViewController {
        عودة ScreenOneCoordinator . المشهد ( العنوان : الذات . العنوان )
    }
}

هيكل ScreenTwoAction : Action {
    اسمحوا العنوان : سلسلة
    اسمحوا العنوان الفرعي : سلسلة

    func scene ( ) - > UIViewController {
        عودة الشاشة اثنين من المنسقين . المشهد ( العنوان : الذات . العنوان ، العنوان الفرعي : الذات . العنوان الفرعي )
    }
}

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

 منسق المنزل من الدرجة النهائية : المنسق {
    مشهد func ثابت ( ) - > UIViewController {
        // إنشاء ViewController وجميع مكونات العمارة لهذا المشهد ...
        العودة التي تم إنشاؤهاViewController
    }
}

الدرجة النهائية ScreenOneCoordinator : المنسق {
    مشهد func ثابت ( ) - > UIViewController {
        // إنشاء ViewController وجميع مكونات العمارة لهذا المشهد ...
        العودة التي تم إنشاؤهاViewController
    }
}

آخر فئة ScreenTwoCoordinator : المنسق {
    مشهد func ثابت ( ) - > UIViewController {
        // إنشاء ViewController وجميع مكونات العمارة لهذا المشهد ...
        العودة التي تم إنشاؤهاViewController
    }
}

وتجدر الإشارة أيضًا إلى أنه على الرغم من نمط التصميم المعماري المختار (MVC أو MVP أو MVVM-C أو VIPER-C أو VIP أو أي بنية أخرى تستخدم منسقًا لإنشاء مشاهد والانتقال من مشهد إلى آخر) ، فإن التنفيذ باستخدام التطوير المستند إلى الخلفية والعمل مناسب تمامًا.

بالنسبة لسياق Actions MovilePay ، استخدمنا نفس نوع المحو المستخدم في عناصر واجهة المستخدم ، مع تعديل طفيف.

 الفئة النهائية AnyAction : قابلة للفك {

    مفاتيح ترميز التعداد الخاص : CodingKey {
        معرف الحالة
    }

    دعونا العمل : العمل ؟

    المطلوب init ( من وحدة فك الترميز : Decoder ) رميات {
        افعل _
            دع الحاوية = جرب وحدة فك التشفير . حاوية ( keyedBy : CodingKeys . self )
            دعونا اكتب = جرب الحاوية . فك الشفرة ( ActionIdentifier . self ، forKey :. identifier )
            النفس . العمل = حاول الكتابة . metatype . الحرف الأول ( من : مفكك الشفرة )
        } قبض {
            النفس . العمل = لا شيء
        }
    }
}

ملاحظة ذات صلة هنا هي أن MovilePay يمكن أن يستخدم نمط تصميم Generics لتجنب تكرار رمز محو النوع. ومع ذلك ، اختاروا عدم القيام بذلك. فيما يلي مثال على بنية تحتوي على إجراء.

 بناء ResponseModelForActions : قابل للفك {
    مفاتيح ترميز التعداد الخاصة"مشغل الرمز المميز">: CodingKey { case action ، text } let action : Action ؟ let text : String init ( from decoder : Decoder ) رميات { let container = try decoder . حاوية ( keyedBy : CodingKeys . self ) self . نص = جرب الحاوية . فك الشفرة ( String . self ، forKey :. text ) دع anyAction = try ؟ الحاوية . فك شفرة ( AnyAction . self ، forKey :. action ) self . الإجراء = anyAction ؟. عمل } }

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

 {
    "نص" : "نص توضيحي" ،
    "الإجراء" : {
        "المعرف" : "HOME_SCREEN"
    }
}

تم تحقيق ذلك بسهولة من خلال توسيع بروتوكول المنسق للسماح لجميع المنسقين بالحصول على مشهد جديد عبر كائن الإجراءات.

يسمح للمنسق بالتصرف ، أي إنشاء مثيل UIViewController التالي لهذا الإجراء ثم عرضه.

 منسق تمديد {
    func scene ( باستخدام action : Action ) - > UIViewController {
        عودة العمل . مشهد ( )
    }
}

تلميح حول تنفيذ الخادم

ربما تتساءل كيف يبدو كل هذا على جانب الخادم. كيف لا تخلط بين خدماتك وقدراتك الأساسية والمعلومات الخارجية؟ سر النجاح في تطوير البرمجيات هو العمل في طبقات.

لذلك ، بالإضافة إلى جميع الخدمات الأساسية المعقدة ، أضافت MovilePay طبقة أخرى إلى الخادم ، والتي ، من خلال تلخيص جميع الخدمات الأخرى وتطبيق منطق التطبيق بالكامل ، تحول البيانات إلى الاستجابة المتوقعة من الواجهة الأمامية. تسمى هذه الطبقة BFF ، أو Backend For Frontend هي طبقة توفر الاتصال بين طرفين منفصلين وغير مرتبطين بالنظام. إنه المكان الذي يتم فيه تكوين السلاسل والصور والتدفقات واختلافات الأنماط وتطبيقها على البيانات الأساسية قبل إرسالها إلى التطبيقات.

الاستنتاجات

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

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

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