Валидация данных в Swift (iOS/macOS): обзор инструментов и библиотек
Валидация данных — один из ключевых аспектов разработки качественных мобильных и десктопных приложений на Swift. Она позволяет гарантировать, что вводимые пользователем данные соответствуют ожидаемому формату и бизнес-правилам. В этой статье мы рассмотрим основные подходы, встроенные механизмы и популярные библиотеки для валидации в экосистеме Apple.
Почему важна валидация?
Без валидации приложение рискует получить некорректные данные, что может привести к:
- Ошибкам в работе серверной части
- Неожиданным сбоям (crash) на стороне клиента
- Уязвимостям безопасности (SQL-инъекции, XSS)
- Плохому пользовательскому опыту
Встроенные возможности Swift и Foundation
Swift и фреймворк Foundation предоставляют базовые, но мощные инструменты для валидации.
1. Проверка с помощью NSPredicate
NSPredicate — мощный инструмент для фильтрации и проверки данных. Он поддерживает регулярные выражения, что делает его удобным для валидации email, телефонов и других строк.
import Foundation
func isValidEmail(_ email: String) -> Bool {
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let predicate = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return predicate.evaluate(with: email)
}
// Пример использования
let testEmail = "user@example.com"
print(isValidEmail(testEmail)) // true
2. Валидация через NSRegularExpression
Для более сложных сценариев удобно использовать NSRegularExpression.
func isValidPassword(_ password: String) -> Bool {
// Минимум 8 символов, одна заглавная, одна строчная, одна цифра
let passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{8,}$"
do {
let regex = try NSRegularExpression(pattern: passwordRegex)
let range = NSRange(location: 0, length: password.utf16.count)
return regex.firstMatch(in: password, options: [], range: range) != nil
} catch {
return false
}
}
print(isValidPassword("Swift1234")) // true
print(isValidPassword("swift123")) // false (нет заглавной)
Популярные библиотеки для валидации
Хотя встроенные средства достаточны для простых задач, для сложных форм с множеством правил удобнее использовать специализированные библиотеки.
1. Validator (от Adam Waite)
Одна из самых популярных библиотек для валидации строк в Swift. Поддерживает цепочки правил (chain validation) и кастомные валидаторы.
// Установка через SPM: .package(url: "https://github.com/adamwaite/Validator.git", from: "3.0.0")
import Validator
let emailRule = ValidationRulePattern(pattern: EmailValidationPattern.standard, error: "Некорректный email")
let nameRule = ValidationRuleLength(min: 2, max: 50, error: "Имя должно быть от 2 до 50 символов")
let email = "test@mail.ru"
let result = email.validate(rule: emailRule)
switch result {
case .valid:
print("Email корректен")
case .invalid(let errors):
print(errors.first?.message ?? "Ошибка")
}
2. SwiftValidators (от gkaimakas)
Легковесная библиотека с декларативным синтаксисом. Отлично подходит для проверки полей в реальном времени.
import SwiftValidators
let phone = "+7 (999) 123-45-67"
if Validator.isPhoneNumber().trim().validate(phone) {
print("Телефон валидный")
} else {
print("Неверный формат")
}
Валидация в SwiftUI с помощью Combine
Современные приложения на SwiftUI часто используют Combine для реактивной валидации. Это позволяет показывать ошибки мгновенно, по мере ввода.
import SwiftUI
import Combine
class RegistrationViewModel: ObservableObject {
@Published var email = ""
@Published var password = ""
@Published var isFormValid = false
private var cancellables = Set<AnyCancellable>()
init() {
// Реактивная проверка
Publishers.CombineLatest($email, $password)
.map { email, password in
let validEmail = email.contains("@") && email.contains(".")
let validPassword = password.count >= 8
return validEmail && validPassword
}
.assign(to: &$isFormValid)
}
}
struct RegistrationView: View {
@StateObject private var viewModel = RegistrationViewModel()
var body: some View {
Form {
TextField("Email", text: $viewModel.email)
.autocapitalization(.none)
SecureField(" Также в библиотеке
Bean Validation (Jakarta Validation) — Валидация данных в Java
proptest для Rust: полное руководство с примерами
Работа с XML в Go (Golang): пакет encoding/xml и альтернативы