التحقق من صحة حقل IOS - سريع وسهل

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

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

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

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

تنصل:
, . . , — .

المهمة الدنيا النموذجية هي كما يلي:

هناك حقول إدخال تسجيل الدخول وكلمة المرور وزر تفويض. من الضروري أن تتغير حالة زر التفويض (isEnable) وفقًا لما هو موجود في حقول الإدخال.

تبدو نسخة أكثر تقدمًا قليلاً من هذه المهمة كما يلي:

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

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

ليما حول مطور كسول
, , . (« » ), , .

الفكرة العامة للمقترح هي كما يلي:

هناك فئة لحقل المدخلات وفئة لمدير المصادقة. حقل الإدخال موروث ، كما هو متوقع ، من UITextField. مدير التحقق - الموروث من UIControl ، يحتوي على مجموعة من العناصر التي تم التحقق من صحتها (ليس من الضروري على الإطلاق أن يكون من نسل UITextField) وينفذ نمط "المراقب". بالإضافة إلى ذلك ، يعمل كمدير لعناصر التحكم الأخرى التي يجب أن تغير حالة إمكانية الوصول الخاصة بها عندما تتغير حالة العناصر التي تم التحقق من صحتها. بمعنى آخر ، إذا كان الحقل يحتوي على بريد إلكتروني غير صالح ، فيجب ألا يكون زر التسجيل متاحًا.



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

@objc protocol IValidatable : class {
    varisValid: Bool { get }
}

لإضافة التحقق من الصحة إلى مشروعك ، تحتاج إلى إضافة 4 ملفات من المثال الموجود في مستودع GitHub .

  • تطبق فئة DSTextField حقل إدخال مع الإشارة إلى عملية التحقق من الصحة.
  • فئة DSValidationManager هي مراقب يوفر الوظائف التي نحتاجها.
  • امتداد StringOptional + Utils - يحتوي على طريقة واحدة فقط تستخدم تعبيرًا عاديًا للتحقق مما إذا كان نص السطر الحالي صالحًا.
  • UIView + Layer هي مجرد طريقة ملائمة لإضافة إطار بعرض معين لأي سليل لـ UIView.

بالمعنى الدقيق للكلمة ، إذا كنت ترغب في تنفيذ التحقق بنفس الطريقة لأي عنصر تحكم آخر ، فأنت على الأرجح تحتاج فقط إلى DSValidationManager. يتم استخدام الباقي فقط لراحتك.

تظهر عملية التحقق في الفيديو (gif).


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

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

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



لاحظ القارئ اليقظ أنه على يمين المستجيب هو كائن من لوحة مكون Xcode القياسية. لذلك ، تم تجاوز المعلمة Class بواسطة فئة DSValidationManager . تم تنفيذ الخدعة نفسها لحقول الإدخال ، والفرق الوحيد هو استخدام فئة DSTextField هناك .

الآن تأتي جميع برامجنا إلى الخطوات البسيطة التالية:

  1. قم بربط مجموعة VerifiedControls من ValidationManager مع حقول الإدخال.


  2. قم بربط مجموعة managerControls من ValidationManager بالزر الذي تريد إدارته.


  3. قم بربط حقول الإدخال في الاتجاه المعاكس مع ValidationManager ، مما يجعلها مفوضًا.

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


رمز DSValidationManager بدائي قبيح.

import UIKit

@objc protocol IValidationManager : class {
    func verificated()
}

@objc protocol IValidatable : class {
    var isValid: Bool { get }
}

class DSValidationManager : UIControl, IValidationManager
{
    @IBOutlet var verifiedControls: [UIControl]?
    @IBOutlet var managedControls: [UIControl]?

    private (set) var valid : Bool = false {
        didSet {
            self.sendActions(for: .valueChanged)
        }
    }
    
    overrideinit(frame: CGRect) {
        super.init(frame: frame)
        self.verificated()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.verificated()
    }

    func verificated() {
        self.checkVerifiedControls()
        self.controlsAction()
    }

    private func checkVerifiedControls() {
        guard let list:[IValidatable] = self.verifiedControls?.filter({$0 isIValidatable}) as? [IValidatable]
            else { return }
        self.valid = list.filter({!$0.isValid}).count==0
    }
    
    private func controls Action() {
        guard let list = self.managedControls else { return }
        for item in list {
            item.isEnabled = self.valid
        }
    }
}

كما ترون ، يتلقى إشعارًا من مجموعة واحدة ويتصرف على مجموعة أخرى.

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

من بين جميع رموز TextEdit ، تجدر الإشارة فقط إلى أن الحقل يجب أن يهتم بتعيين خاصية " isValid " بشكل صحيح وسحب طريقة " Verified ()""من مندوبه. ومع ذلك ، لاحظ أن حقل الإدخال لا يستخدم مرجعًا لكائن المدير ، ولكنه يستخدم مجموعة. هذا يسمح لك بربط حقل الإدخال بالعديد من المديرين.

وبناءً على ذلك ، يجب سحب الطريقة من قبل كل من المندوبين.

    var isValid: Bool {
        return self.text.verification(self.expression, required:self.valueRequired)
    }

    @IBOutlet var validateDelegates: [IValidationManager]?

    private func handleDelegateAction(_ sender: UITextField) {
        guard let list = self.validateDelegates else { return }

        for validateDelegate in list {
            validateDelegate.verificated()
        }
    }

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


بشكل عام ، يمكن استخدام الحيلة باستخدام "الكائن" في رأس النموذج على نطاق أوسع بكثير من مجرد التحقق من صحة الحقل - فهي تتفاعل مع MVP إلى MVVM بدون أي Rx. الاستخدام الأكثر شيوعًا هو مشاركة الشبكة والإخطار بالتغييرات في نموذج CoreData.

All Articles