استخدام SwiftLint Static Code Analyzer في تطبيقات iOS المصرفية عبر الهاتف المحمول

أوليغ إيفانوف ، رئيس مركز الكفاءات لقنوات الخدمة عن بعد



مرحبًا بالجميع! كما وعدت في مقال "الخدمات المصرفية عبر الهاتف المحمول من التصنيف الدولي للأمراض: تاريخ التنمية" ، أريد اليوم أن أتحدث عن محللي الشفرة الثابتة وتجربة تطبيقهم في تطبيقات الهاتف المحمول التي تعمل بنظام iOS.

دعنا نحدد الهدف الذي نريد تحقيقه باستخدام مجموعة الأدوات هذه:

  • الكشف المبكر عن الأخطاء وأوجه القصور ؛
  • Code Style ( — , ).

طريقة شائعة لتحقيق أهدافنا هي التحقق يدويًا من الكود - مراجعة الكود .

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

هنا يأتي محللو الكود الثابت لمساعدتنا.

محللات رمز ثابت- بدء عملية تلقائية للكشف عن الأخطاء والعيوب في شفرة مصدر البرامج.

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

بصفتنا محلل رمز ثابت في مشاريع iOS لدينا ، نستخدم SwiftLint.

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

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



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



للتعرف على الأداة ، أوصي بقراءة الوثائق الرسمية .

تثبيت SwiftLint بسيط:

  1. أضف pod "SwiftLint" إلى ملف المشروع
  2. قم بإضافة "مرحلة تشغيل البرنامج النصي" الجديدة إلى المشروع.

    "${PODS_ROOT}/SwiftLint/swiftlint"
  3. SwiftLint .swiftlint.yml
  4. .swiftlint.yml , SwiftLint

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



بين قوسين أيضًا ، يعرض اسم القاعدة التي بدأت التوصية (operator_usage_whitespace) .

في هذه الحالة ، هذه هي:

مسافات استخدام
عامل التشغيل يجب أن يحيط عامل التشغيل بمسافة واحدة.

الرمز الصحيح: الرمز




الموصى به:



تحتوي كل قاعدة على مجموعة من السمات:

المعرّف : operator_usage_whitespace
ممكن بشكل افتراضي : معطل
مدعوم من التصحيح التلقائي :نعم
النوع : قاعدة محلل النمط : لا يوجد إصدار الحد الأدنى من مترجم Swift : 3.0.0 التكوين الافتراضي : تحذير انتبه إلى "الحد الأدنى من إصدار مترجم Swift" - اربط استخدام القواعد بهذه السمة وإعدادات مشروعك. تُظهر السمة "التكوين الافتراضي" كيف سيتم إدراك القواعد التي تحتوي على هذه السمة: إما تحذير عادي ، أو خطأ تجميع ، مثل قاعدة فرض الإرسال (التكوين الافتراضي: خطأ) يمكن العثور على جميع القواعد في وثائق ملائمة للغاية وموضحة








.

أدناه سوف أعرض القواعد التي اخترناها في فريقنا ، يمكنك استخدامها كمثال لإنشاء مشروعك.

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

وظيفية :

- private_outlet
- force_unwrapping
- force_cast
- force_try
- strong_iboutlet
- private_action
- block_based_kvo
- contains_over_first_not_nil
- discarded_notification_center_observer
- discouraged_direct_init
- discouraged_object_literal
- discouraged_optional_boolean
- discouraged_optional_collection
- duplicate_imports
- dynamic_inline
- empty_count
- empty_parameters
- empty_parentheses_with_trailing_closure
- empty_string
- explicit_enum_raw_value
- function_default_parameter_at_end
- generic_type_name
- identical_operands
- implicit_getter
- is_disjoint
- notification_center_detachment
- nsobject_prefer_isequal
- redundant_set_access_control
- unused_capture_list

اسلوب :

- unneeded_parentheses_in_closure_argument
- let_var_whitespace
- yoda_condition
- القولون
- فاصلة
- closure_parameter_position
- closure_spacing
- collection_alignment
- leading_whitespace
- علامة
- opening_brace
- operator_usage_whitespace
- operator_whitespace
- protocol_property_accessors_order
- return_arrow_whitespace
- switch_case_alignment
- statement_position
- trailing_comma
- trailing_newline
- unneeded_break_in_switch
- custom_rules
- closure_end_indentation
- file_name_no_space
- unowned_variable_capture
- no_space_in_method_call
- contains_over_filter_count
- contains_over_filter_is_empty
- contains_over_range_nil_comparison
- duplicate_enum_cases
- empty_collection_literal

أيضا الهدف من SwiftLint اخترنا فقط كتالوج مع رمز قاعدة لدينا عن طريق إضافة الإعدادات المناسبة في .swiftlint.yml ملف التكوين:

ما يلي:

- <دليل رمز قاعدة>


لقد قمنا بإنشاء قاعدة للحصول على جواز وظائف الطباعة. الطباعة عملية صعبة للغاية. عبر ملف التكوين. swiftlint.yml:

custom_rules:
  disable_print:
    included: ".*\\.swift"
    name: "print usage"
    regex: "((\\bprint)|(Swift\\.print))\\s*\\("
    message: "Prefer os_log over print"
    severity: error

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

func logApp(level: Constants.LogLevel, items: Any...) {
    if Constants.logLevel == .none {
        return
    }
    
    if level.rawValue <= Constants.logLevel.rawValue {
        // swiftlint:disable disable_print
        if let strings = items as? [String] {
            for string in strings {
                print(string)
            }
        } else {
            print(items)
        }
        // swiftlunt:enable disable_print
    }

ولكن من أجل استخدام وظيفة الطباعة ، كان علينا إغلاق المكالمة في وظيفة التسجيل الخاصة بنا باستخدام SwiftLint لتجاهل قواعدنا الخاصة في كتلة التعليمات البرمجية المميزة بإرشادات خاصة.

// swiftlint:disable disable_print
// swiftlunt:enable disable_print

لدى SwiftLint القدرة على تجاهل قواعدها الخاصة:

// swiftlint:disable <rule1 [rule2 rule3…]>
<,   SwiftLint   rule1 [rule2 rule3…]>
// swiftlunt:enable <rule1 [rule2 rule3…]>

أو

// swiftlint:disable all
<,   SwiftLint   >
// swiftlint:enable all

استغل هذه الفرصة ، مدركًا تمامًا أنها ضرورية!

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

الكل! الآن SwiftLint معك إلى الأبد :)


All Articles