You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI Combine框架下ViewModel中合并实现邮箱校验的方法

实现方案

步骤1:将邮箱正则校验封装为String扩展

你原来的isValidEmail方法本质是String的校验工具,先把它封装成String的扩展方便全局调用:

extension String {
    func isValidEmail() -> Bool {
        let emailRegEx = "(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}" + "~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\" + "x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-" + "z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?|\\[(?:(?:25[0-5" + "]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-" + "9][0-9]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21" + "-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"
        let emailValidation = NSPredicate(format:"SELF MATCHES[c] %@", emailRegEx)
        return emailValidation.evaluate(with: self)
    }
}

步骤2:完善RegisterViewModel属性定义

确保你的ViewModel满足以下基础定义,核心是email和emailMessage都用@Published修饰,这样View才能监听到变化:

import Combine
class RegisterViewModel: ObservableObject {
    // 用户输入的邮箱
    @Published var email = ""
    // 邮箱校验提示信息,View直接监听该字段
    @Published var emailMessage = ""
    // 你原来用到的类型别名
    typealias ValidatePublisher = AnyPublisher<Bool, Never>
    // 持有订阅,避免信号被释放
    private var cancellables = Set<AnyCancellable>()
    
    init() {
        // 订阅邮箱校验 publisher,触发校验逻辑
        isEmailValidPublisher
            .sink(receiveValue: { _ in })
            .store(in: &cancellables)
    }
    
    // 这里放修改后的isEmailValidPublisher
}

步骤3:修改isEmailValidPublisher实现

把原来仅判断长度的逻辑,替换为「长度校验+正则校验」的组合逻辑:

private var isEmailValidPublisher: ValidatePublisher {
    $email
        .removeDuplicates()
        .map { email in
            // 先去除首尾空格换行
            let trimmedEmail = email.trimmingCharacters(in: .whitespacesAndNewlines)
            // 先判断长度不小于10,再走正则校验
            guard trimmedEmail.count >= 10 else { return false }
            return trimmedEmail.isValidEmail()
        }
        .handleEvents(receiveOutput: { [weak self] isValid in
            self?.emailMessage = isValid ? "" : "Invalid email"
        })
        .eraseToAnyPublisher()
}

步骤4:View层直接调用即可

你原本写的View层代码不需要任何修改,自动监听emailMessage的变化切换图标颜色:

Image(systemName: "envelope")
    .foregroundColor(registerVM.emailMessage != "" ? .red : .blue)

内容的提问来源于stack exchange,提问作者Mert Köksal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 10:57:03