例:
-パスワードの長さが6文字を超えている
-少なくとも1桁
-大文字と小文字
多くの場合、このような要件は次のように実装されます。
func isPasswordCorrect(_ value:String) -> Bool { // code for check length, number exist, uppercase and lowercase chars }
シンプル。 関数が機能し、パスワードがチェックされます。 誰もが幸せです。
さらに、電子メールフィールドの正確性を確認する必要がある場合は、次のような関数も作成します。
func isEmailCorrect(_ value:String) -> Bool { // code for check length, number exist, uppercase and lowercase chars }
などなど。
プロジェクトが成長するにつれて、このようなチェックを行う機能が増えています。 新しいプロジェクトを作成するときは、最初からやり直すか、これらの関数を前のプロジェクトからコピーする必要があります。 あまり便利ではありません。 解決策の1つ。
ある時点で、私はこの問題を解決する時であることに気付きました。
明らかな解決策は、バリデータを作成することでした。
実際、私は新しいものを思いつきませんでした。そのようなバリデータはすでに存在し、githubで簡単に見つけることができます。 しかし、目標はあなた自身のものを書くことでした。
主なタスクは次のとおりです。
-どこからでも電話をかける普遍的な方法で、すぐに結果が得られます
-簡単なセットアップ、検証基準の迅速な指定
-スケーラビリティ。
最初のステップは、基準の作成方法を決定することでした。 このためのプロトコルが作成されました。
public protocol Criteriable { /// debug string for debug description of problem var debugErrorString : String {get} /// Check if value conform to criteria /// /// - Parameter value: value to be checked /// - Returns: return true if conform func isConform(to value:String) -> Bool }
まず、長さのチェック、レジスタが実装されました。 次のようになります。
LowercaseLetterExistCriteria
public struct LowercaseLetterExistCriteria : Criteriable { public var debugErrorString: String = debugMessage(LowercaseLetterExistCriteria.self, message:"no lowercase char exists") public init(){} public func isonform(to value: String) -> Bool { for char in value.characters { if char.isLowercase() == true { return true } } return false } }
NumberExistCriteria
public struct NumberExistCriteria : Criteriable { public var debugErrorString: String = debugMessage(NumberExistCriteria.self, message:"no number char exist") public init(){} public func isonform(to value: String) -> Bool { let regExptest = NSPredicate(format: "SELF MATCHES %@", ".*[0-9]+.*") return regExptest.evaluate(with: value) } }
UppercaseLetterExistCriteria
public struct UppercaseLetterExistCriteria : Criteriable { public var debugErrorString: String = debugMessage(UppercaseLetterExistCriteria.self, message:"no uppercase char exists") public init(){} public func isonform(to value: String) -> Bool { for char in value.characters { if char.isUppercase() == true { return true } } return false } }
その後、バリデーター自体が実装されました。
StringValidator
/// Validator public struct StringValidator { /// predictions public var criterias: [Criteriable] ///init public init(_ criterias: [Criteriable]) { self.criterias = criterias } /// validate redictors to comform /// /// - Parameters: /// - value: string than must be validate /// - forceExit: if true -> stop process when first validation fail. else create array of fail criterias /// - result: result of validating public func isValide(_ value:String, forceExit:Bool, result:@escaping (ValidatorResult) -> ()) { // validating code } }
バリデーターは一連の基準で初期化され、フラグが設定され(合格しないすべての基準を収集するか、最初の基準が見つかったときに中断する)、検証される文字列が渡されます。 結果は列挙型です:
/// Validator result object /// /// - valid: everething if ok /// - notValid: find not valid criteria /// - notValide: not valid array of criterias public enum ValidatorResult { case valid case notValid(criteria:Criteriable) case notValides(criterias:[Criteriable]) }
また、スケーラビリティのために、独自の基準を簡単に定義できます。
struct MyCustomCriteria : Criteriable { var debugErrorString: String = debugMessage(MyCustomCriteria.self, message:"some debug message") func isConform(to value: String) -> Bool { /* some logic for check */ return false } }
その結果、必要な機能が得られ、関数を作成する必要がなくなりました。 一連の基準を定義し、それらに対して基準を確認するだけで十分です。
CocoaPodも作成され、すべてのソースコードを確認できます。
おわりに
将来的には、UITextFieldの即時検証のためにバリデーターの機能を拡張する計画があります。
文字列だけでなく、オブジェクトをチェックするために機能を拡張するというアイデアもあります。
この資料が役立つことを願っています。
ご清聴ありがとうございました。