ios - iOS 中的 MVVM 模型

标签 ios swift mvvm swift4

这是一个User 模型类。该模型将成为注册新用户、记录已注册用户和显示个人资料时的数据容器。

struct User {

    typealias message = (Bool,String)

    var name: String?
    var username: String
    var password: String
    var image: String?

    func isValidForLogin() -> message {

        let emailMessage = isValidEmail(testStr: username)
        let passwordMessage = isValidPassowrd(testStr: password)

        if emailMessage.0 && passwordMessage.0 {
            return (true,"Valid")
        }

        if !emailMessage.0{
            return (emailMessage.0, emailMessage.1)
        }else{
            return (passwordMessage.0, passwordMessage.1)
        }
    }

    func isValidForRegister() -> message {
        if let name = self.name{
            let nameMessage = isValidName(testStr: name)
            let emailMessage = isValidEmail(testStr: username)
            let passwordMessage = isValidPassowrd(testStr: password)

            if emailMessage.0 && passwordMessage.0 && nameMessage.0{
                return (true,"Valid")
            }

            if !emailMessage.0{
                return (emailMessage.0, emailMessage.1)
            }else if !passwordMessage.0{
                return (passwordMessage.0, passwordMessage.1)
            }else{
                return (nameMessage.0, nameMessage.1)
            }
        }
         return (false, "Name " + Constants.emptyField)
    }

    private func isValidName(testStr: String) -> message{
        if testStr.isEmpty{
            return (false, "Name " + Constants.emptyField )
        }
        return (true, "Valid")
    }

    private func isValidPassowrd(testStr: String) -> (Bool, String) {
        if testStr.isEmpty{
            return (false, "Password " + Constants.emptyField )
        }

        if testStr.count > 6{
            return (true, "Valid")
        }
        return (false, Constants.invalidPassword)
    }

    private func isValidEmail(testStr: String) -> message {

        if testStr.isEmpty{
            return (false, "Email " + Constants.emptyField)
        }

        let emailRegEx = "^(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?(?:(?:(?:[-A-Za-z0-9!#$%&’*+/=?^_'{|}~]+(?:\\.[-A-Za-z0-9!#$%&’*+/=?^_'{|}~]+)*)|(?:\"(?:(?:(?:(?: )*(?:(?:[!#-Z^-~]|\\[|\\])|(?:\\\\(?:\\t|[ -~]))))+(?: )*)|(?: )+)\"))(?:@)(?:(?:(?:[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)(?:\\.[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)*)|(?:\\[(?:(?:(?:(?:(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))\\.){3}(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))))|(?:(?:(?: )*[!-Z^-~])*(?: )*)|(?:[Vv][0-9A-Fa-f]+\\.[-A-Za-z0-9._~!$&'()*+,;=:]+))\\])))(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?$"
        let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
        let result = emailTest.evaluate(with: testStr)
        if result{
            return (result, "Valid")
        }else{
            return (result, Constants.invalidEmail)
        }
    }
}

我正在尝试遵循 MVVM 模式。所以,我的 RegisterViewViewModelViewModel 类:

struct RegisterViewModel {

    private let minUserNameLength = 4
    private let minPasswordLength = 6

    var name: String
    var email: String
    var password: String

    private var userModel: User{
        return User(name: name, username: email, password: password, image: "")
    }

    func isValid() -> (Bool, String) {
        return userModel.isValidForRegister()
    }

    func register(){
        ....
    }

}

在我的 RegisterViewController 中:

class RegisterViewController: UIViewController{

    @IBOutlet weak var txtName: UITextField!
    @IBOutlet weak var txtUsername: UITextField!
    @IBOutlet weak var txtPassword: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func btnSignUpPressed(_ sender: UIButton) {
        if let name = txtName.text, let email = txtUsername.text, let password = txtPassword.text{
            let userModel = RegisterViewModel(name: name, email: email, password: password)
            let validate = userModel.isValid()

            if validate.0{
                userModel.register()
            }else{
                //do error handling here
                print(validate.1)
            }
        }
    }
}

我的方向正确吗?任何建议将不胜感激。

最佳答案

我建议您将 RxSwiftMVVM 一起使用。您也可以将验证导出到单独的 ValidationService 类。否则,您可能必须在不同模型之间复制相同的验证方法。

enum ValidationResult {
    case ok
    case empty
    case validating
    case failed(message: String)
}

extension ValidationResult {
    var isValid: Bool {
        switch self {
        case .ok:
            return true
        default:
            return false
        }
    }

    var isEmpty: Bool {
        switch self {
        case .empty:
            return true
        default:
            return false
        }
    }
}

class ValidationService {

    let minPasswordCount = 4

    static let shared = ValidationService()

    func validateName(_ name: String) -> Observable<ValidationResult> {
        if name.isEmpty {
            return .just(.empty)
        }

        if name.rangeOfCharacter(from: CharacterSet.decimalDigits) != nil {
            return .just(.failed(message: "Invalid name"))
        }

        return .just(.ok)
    }
}

关于ios - iOS 中的 MVVM 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49049087/

相关文章:

c# - 工具栏拖动绑定(bind)失败

MvvmCross 对话框

ios - 从 iOS SDK 使用 Apple Pay

iOS:如何禁用 tableview 中的反弹效果?

ios - Swift:使用 slider 修改图像 - 并隔离以优化 CIImage?

ios - 来自 firebase 控制台 iOS 12.2 的推送通知不起作用

c# - 中断后如何连续滚动到scrollviewer MVVM的底部

iphone - 在 UIWebView 中显示特定的 Layout

swift - 如何检查一个字符串是否包含另一个字符串但字符可能不同?

swift - 区分天数并快速显示标签