Skip to content

Commit b6ad33b

Browse files
committed
Implement Custom Validation Messages With localization support
1 parent c7a935d commit b6ad33b

24 files changed

+300
-81
lines changed

Package.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import PackageDescription
44

55
let package = Package(
66
name: "ValidatorKit",
7+
defaultLocalization: "en",
78
platforms: [
89
.iOS(.v13),
910
.macOS(.v10_15),
@@ -17,7 +18,11 @@ let package = Package(
1718
],
1819
targets: [
1920
.target(
20-
name: "ValidatorKit"),
21+
name: "ValidatorKit",
22+
resources: [
23+
.process("Resources/Localization")
24+
]
25+
),
2126
.testTarget(
2227
name: "ValidatorKitTests",
2328
dependencies: ["ValidatorKit"]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// Localizable.strings
3+
// ValidatorKit
4+
//
5+
// Created by Alhiane on 26/9/2024.
6+
//
7+
8+
/* Localizable.strings (Arabic) */
9+
"validation.custom" = "فشلت عملية التحقق.";
10+
"validation.email" = "يرجى إدخال عنوان بريد إلكتروني صالح.";
11+
"validation.min" = "يجب أن تكون القيمة على الأقل %@.";
12+
"validation.max" = "يجب ألا تتجاوز القيمة %@.";
13+
"validation.numeric" = "يرجى إدخال قيمة رقمية.";
14+
"validation.date" = "يرجى إدخال تاريخ صالح.";
15+
"validation.range" = "يجب أن تكون القيمة بين %@ و %@.";
16+
"validation.pattern" = "القيمة لا تتطابق مع النموذج المطلوب.";
17+
"validation.url" = "يرجى إدخال عنوان URL صالح.";
18+
"validation.inArray" = "يجب أن تكون القيمة واحدة من الخيارات المسموح بها.";
19+
"validation.requiredIf" = "هذا الحقل مطلوب بناءً على الشرط المحدد.";
20+
"validation.required" = "هذا الحقل مطلوب.";
21+
"validation.greaterThan" = "يجب أن تكون القيمة أكبر من %@.";
22+
"validation.lessThan" = "يجب أن تكون القيمة أقل من %@.";
23+
"validation.mimeTypes" = "يجب أن يكون نوع الملف واحدًا من الأنواع المسموح بها: %@.";
24+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// Localizable.strings
3+
// ValidatorKit
4+
//
5+
// Created by Alhiane on 26/9/2024.
6+
//
7+
8+
/* Localizable.strings (English) */
9+
"validation.custom" = "Validation failed.";
10+
"validation.email" = "Please enter a valid email address.";
11+
"validation.min" = "Value must be at least %@.";
12+
"validation.max" = "Value must be no more than %@.";
13+
"validation.numeric" = "Please enter a numeric value.";
14+
"validation.date" = "Please enter a valid date.";
15+
"validation.range" = "Value must be between %@ and %@.";
16+
"validation.pattern" = "Value does not match the required pattern.";
17+
"validation.url" = "Please enter a valid URL.";
18+
"validation.inArray" = "Value must be one of the allowed options.";
19+
"validation.requiredIf" = "This field is required based on the specified condition.";
20+
"validation.required" = "This field is required.";
21+
"validation.greaterThan" = "Value must be greater than %@.";
22+
"validation.lessThan" = "Value must be less than %@.";
23+
"validation.mimeTypes" = "File type must be one of the allowed types: %@.";
24+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// Localizable.strings
3+
// ValidatorKit
4+
//
5+
// Created by Alhiane on 26/9/2024.
6+
//
7+
8+
/* Localizable.strings (Spanish) */
9+
"validation.custom" = "La validación falló.";
10+
"validation.email" = "Por favor, introduce una dirección de correo electrónico válida.";
11+
"validation.min" = "El valor debe ser al menos %@.";
12+
"validation.max" = "El valor no debe exceder %@.";
13+
"validation.numeric" = "Por favor, introduce un valor numérico.";
14+
"validation.date" = "Por favor, introduce una fecha válida.";
15+
"validation.range" = "El valor debe estar entre %@ y %@.";
16+
"validation.pattern" = "El valor no coincide con el patrón requerido.";
17+
"validation.url" = "Por favor, introduce una URL válida.";
18+
"validation.inArray" = "El valor debe ser una de las opciones permitidas.";
19+
"validation.requiredIf" = "Este campo es obligatorio según la condición especificada.";
20+
"validation.required" = "Este campo es obligatorio.";
21+
"validation.greaterThan" = "El valor debe ser mayor que %@.";
22+
"validation.lessThan" = "El valor debe ser menor que %@.";
23+
"validation.mimeTypes" = "El tipo de archivo debe ser uno de los tipos permitidos: %@.";
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// Localizable.strings
3+
// ValidatorKit
4+
//
5+
// Created by Alhiane on 26/9/2024.
6+
//
7+
8+
/* Localizable.strings (French) */
9+
"validation.custom" = "La validation a échoué.";
10+
"validation.email" = "Veuillez saisir une adresse e-mail valide.";
11+
"validation.min" = "La valeur doit être au moins %@.";
12+
"validation.max" = "La valeur ne doit pas dépasser %@.";
13+
"validation.numeric" = "Veuillez saisir une valeur numérique.";
14+
"validation.date" = "Veuillez saisir une date valide.";
15+
"validation.range" = "La valeur doit être entre %@ et %@.";
16+
"validation.pattern" = "La valeur ne correspond pas au modèle requis.";
17+
"validation.url" = "Veuillez saisir une URL valide.";
18+
"validation.inArray" = "La valeur doit être l'une des options autorisées.";
19+
"validation.requiredIf" = "Ce champ est obligatoire en fonction de la condition spécifiée.";
20+
"validation.required" = "Ce champ est obligatoire.";
21+
"validation.greaterThan" = "La valeur doit être supérieure à %@.";
22+
"validation.lessThan" = "La valeur doit être inférieure à %@.";
23+
"validation.mimeTypes" = "Le type de fichier doit être l'un des types autorisés : %@.";
24+

Sources/ValidatorKit/Rules/AnyValidationRule.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
//
77
public struct AnyValidationRule: ValidationRule {
88
private let _validate: (Any?) -> ValidationError?
9+
public let message: String
910

1011
public init<R: ValidationRule>(_ rule: R) {
1112
_validate = rule.validate
13+
self.message = rule.message
1214
}
1315

1416
public func validate(_ value: Any?) -> ValidationError? {

Sources/ValidatorKit/Rules/DateRule.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77
import Foundation
88

99
public struct DateRule: ValidationRule {
10-
public init() {}
10+
public let message: String
11+
12+
public init(message: String? = nil) {
13+
self.message = message ?? ValidationMessage.message(for: ValidationMessage.dateKey, defaultMessage: ValidationMessage.date)
14+
}
1115

1216
public func validate(_ value: Any?) -> ValidationError? {
1317
if !(value is Date) {
14-
return ValidationError(message: "Invalid date")
18+
return ValidationError(message: message)
1519
}
1620
return nil
1721
}

Sources/ValidatorKit/Rules/EmailRule.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,23 @@
88
import Foundation
99

1010
public struct EmailRule: ValidationRule {
11-
public init() {}
11+
public let message: String
12+
13+
public init(message: String? = nil) {
14+
self.message = message ?? ValidationMessage.message(for: ValidationMessage.emailKey, defaultMessage: ValidationMessage.email)
15+
16+
}
1217

1318
public func validate(_ value: Any?) -> ValidationError? {
1419
guard let email = value as? String else {
15-
return ValidationError(message: "Invalid email format")
20+
return ValidationError(message: message)
1621
}
1722

1823
let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
1924
let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailRegex)
2025

2126
guard emailPredicate.evaluate(with: email) else {
22-
return ValidationError(message: "Invalid email format")
27+
return ValidationError(message: message)
2328
}
2429

2530
return nil

Sources/ValidatorKit/Rules/FileExtensionsRule.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77

88
public struct FileExtensionsRule: ValidationRule {
99
private let allowedExtensions: [String]
10+
public let message: String
1011

11-
public init(allowedExtensions: [String]) {
12+
public init(allowedExtensions: [String], message: String? = nil) {
1213
self.allowedExtensions = allowedExtensions
14+
self.message = message ?? ValidationMessage.message(for: ValidationMessage.mimeTypesKey, defaultMessage: ValidationMessage.mimeTypes)
1315
}
1416

1517
public func validate(_ value: Any?) -> ValidationError? {
1618
guard let filename = value as? String, let fileExtension = filename.split(separator: ".").last?.lowercased() else {
17-
return ValidationError(message: "Invalid file")
19+
return ValidationError(message: ValidationMessage.message(for: ValidationMessage.invalidFileKey, defaultMessage: ValidationMessage.invalidFile))
1820
}
1921

2022
if !allowedExtensions.contains(fileExtension) {
21-
return ValidationError(message: "File extension not allowed")
23+
return ValidationError(message: message)
2224
}
2325
return nil
2426
}

Sources/ValidatorKit/Rules/GreaterThanRule.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55
// Created by Alhiane on 23/9/2024.
66
//
77
public struct GreaterThanRule: ValidationRule {
8+
public let message: String
89
private let minValue: Double
910

10-
public init(minValue: Double) {
11-
self.minValue = minValue
11+
public init(minValue: Double, message: String? = nil) {
12+
self.minValue = minValue
13+
self.message = message ?? ValidationMessage.message(for: ValidationMessage.greaterThanKey, defaultMessage: ValidationMessage.greaterThan,dynamicValues: [String(minValue)])
1214
}
1315

1416
public func validate(_ value: Any?) -> ValidationError? {
15-
guard let doubleValue = value as? Double else { return ValidationError(message: "Invalid value") }
17+
guard let doubleValue = value as? Double else { return ValidationError(message: ValidationMessage.message(for: ValidationMessage.invalidValueKey, defaultMessage: ValidationMessage.invalidValue)) }
1618
if doubleValue <= minValue {
17-
return ValidationError(message: "Must be greater than \(minValue)")
19+
return ValidationError(message: message)
1820
}
1921
return nil
2022
}

0 commit comments

Comments
 (0)