ViewModel函数:无法分配给值:'error'是一个'let'常量

时间:2018-07-13 06:40:12

标签: ios swift

我正在尝试快速学习ViewModel,并且创建了一个函数来处理错误。

但是当我在ViewController文件中调用该函数时,它说:

Cannot assign to value: 'error' is a 'let' constant

有什么办法可以解决这个问题?我仍然是一名寻求最佳建议的学生。

非常感谢。

下面是我的代码,你们能帮我吗?

SignUpError.swift:

class SingUpError {
    func errorMessage(name: String?, lastName: String?,email: String?, password: String?, error: String?){

        enum ErrorMessage: String {
            case noName = "Name cannot be empty"
            case noLastName = "Last name cannot be empty"
            case noEmail = "Email cannot be empty"
            case noPassword = "Password cannot be empty"
        }

        if name == "" {
            error = ErrorMessage.noName.rawValue
        }
    }
}

NewUserVC.swift:

class NewUserVC: UIViewController {

    // Var
    var vm = SingUpError()

    // Outlet Text Fields

    @IBOutlet weak var nameText: UITextField!
    @IBOutlet weak var lastNameText: UITextField!
    @IBOutlet weak var emailText: UITextField!
    @IBOutlet weak var passwordText: UITextField!

    // Outlet Labels

    @IBOutlet weak var nameErrLbl: UILabel!
    @IBOutlet weak var lastNameErrLbl: UILabel!
    @IBOutlet weak var emailErrLbl: UILabel!
    @IBOutlet weak var passwordErrLbl: UILabel!


    @IBAction func submiButton(_ sender: UIButton) {
        submitData()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func submitData() {
        guard
            let name = nameText.text,
            let lastName = lastNameText.text,
            let email = emailText.text,
            let password = passwordText.text
            else {return}

        vm.errorMessage(name: name, lastName: lastName, email: email, password: password, error: nameErrLbl.text)
    }
}

8 个答案:

答案 0 :(得分:0)

您需要执行类似的操作

class SingUpError {
    func errorMessage(name: String?, lastName: String?,email: String?, password: String?, error: String?) -> String{

        var errorMessage : String = ""

        enum ErrorMessage: String {
            case noName = "Name cannot be empty"
            case noLastName = "Last name cannot be empty"
            case noEmail = "Email cannot be empty"
            case noPassword = "Password cannot be empty"
        }

        if name == "" {
            errorMessage = ErrorMessage.noName.rawValue
        }

        return errorMessage
    }
}  

答案 1 :(得分:0)

在swift上声明函数时,其参数默认为'let'常量。而且我们不能将值赋给常量。

在您的情况下,您尝试分配给“错误”变量,该变量是一个参数,因此是一个常量(let)。你不能这样做。

您可能会返回错误消息

class SingUpError {
    func errorMessage(name: String?, lastName: String?,email: String?, password: String?) -> String{

        enum ErrorMessage: String {
            case noName = "Name cannot be empty"
            case noLastName = "Last name cannot be empty"
            case noEmail = "Email cannot be empty"
            case noPassword = "Password cannot be empty"
        }

        if name == "" {
            return ErrorMessage.noName.rawValue
        }

        return ""
    }
}

答案 2 :(得分:0)

我不确定您要使用SingUpError做什么(您是说SignUpError吗?),但这是我的尝试。基本上,我将枚举移出了func,并且让func返回了一个字符串

class SingUpError  {
    enum ErrorMessage: String {
        case noName = "Name cannot be empty"
        case noLastName = "Last name cannot be empty"
        case noEmail = "Email cannot be empty"
        case noPassword = "Password cannot be empty"
    }

    func errorMessage(name: String?, lastName: String?,email: String?, password: String?) -> String? {
        var message: String?

        if name == nil || name.isEmpty {
            message = ErrorMessage.noName.rawValue
        } //else if lastName...

        return message
    }
}

,然后在submitData

if let error = vm.errorMessage(name: name, lastName: lastName, email: email, password: password) {
     nameErrLbl.text = error
}

答案 3 :(得分:0)

您试图将值分配给常量。

您不能这样做,因为error是函数的参数。 如果要从此函数中获取错误消息,则需要编写如下内容:

return ErrorMessage.noName.rawValue

代替

error = ErrorMessage.noName.rawValue

答案 4 :(得分:0)

class SingUpError {
    func errorMessage(name: String?, lastName: String?,email: String?, password: String?) -> String? {

        guard let _ = name else { return ErrorMessage.noName.rawValue }

        // <this seems incomplete, but..>
        enum ErrorMessage: String { 
            case noName = "Name cannot be empty"
            case noLastName = "Last name cannot be empty"
            case noEmail = "Email cannot be empty"
            case noPassword = "Password cannot be empty"
        }

        return nil
    }
}

答案 5 :(得分:0)

首先,将此枚举从SignUpError类中删除

enum ErrorMessage: String {
        case noName = "Name cannot be empty"
        case noLastName = "Last name cannot be empty"
        case noEmail = "Email cannot be empty"
        case noPassword = "Password cannot be empty"
    }

第二,您可以像这样修改您的功能:

func errorMessage(name: String?, lastName: String?,email: String?, password: String?) -> String? {
    if name == "" {
        let error = ErrorMessage.noName.rawValue
        return error
    }
    return nil
}

现在,在ViewController中,您可以修改函数以获取errorMessage

func submitData() {
    //YOUR EXISTING CODE HERE    
    if let errorMessage = vm.errorMessage(name: name, lastName: lastName, email: email, password: password) {
        print("errorMessage:\(errorMessage)")
        return
    }
}

或者您可以尝试使用与您相同的方法,但是将错误传递为inout参数。 similar question here

答案 6 :(得分:0)

正如其他答案所说,您不能将其分配给'error'参数,因为它是一个常量(如果愿意,可以使用let变量)。现在,您可以按照建议的方式修改该函数以返回字符串,但最好采用结构化的方法并实际引发错误。

类似的事情会做:

enum sumbissionErrors: Error {
    case noName
    case noLastName
    case noEmail
    case noPassword

    var description: String {
        switch self {
        case .noName:
            return "Name cannot be empty"
        case .noLastName:
            return "Last name cannot be empty"
        case .noEmail:
            return "Email cannot be empty"
        case .noPassword:
            return "Password cannot be empty"
        }
    }
}

func submitData() throws {
    if nameText.text == nil || nameText.text!.isEmpty {
        throw sumbissionErrors.noName
    }

    if lastNameText.text == nil || lastNameText.text!.isEmpty {
        throw sumbissionErrors.noLastName
    }

    if emailText.text == nil || emailText.text!.isEmpty {
        throw sumbissionErrors.noEmail
    }

    if passwordText.text == nil || passwordText.text!.isEmpty {
        throw sumbissionErrors.noPassword
    }

    // Do whatever you want now that the data is valid.
}

@IBAction func submitButton(_ sender: UIButton) {
    do {
        try submitData()
    }
    catch {
        if let sumbmissionError = error as? sumbissionErrors {
            switch sumbmissionError {
            case .noName:
                nameErrLbl.text = sumbmissionError.description
            case .noLastName:
                lastNameErrLbl.text = sumbmissionError.description
            case .noEmail:
                emailErrLbl.text = sumbmissionError.description
            case .noPassword:
                passwordErrLbl.text = sumbmissionError.description
            }
        } else {
            // This will probably never happen but it indicates that some other more general error occured and needs to be handled here.
        }
    }
}

这只是一个示例,就像您的原件只会抛出遇到的第一个错误。您可能想要重新组织所有内容,以允许标记多个错误。即有可能其中一个以上是空的。

答案 7 :(得分:0)

如果要使用与以前相同的方法,则需要在函数中进行一些细微更改。

第一件事就是让函数参数为常数,这意味着您无法分配值,但是如果仍然需要为参数分配一些值,那么函数中将有一种使用 inout 关键字的方法

class SingUpError {
    func errorMessage(name: String?, lastName: String?,email: String?, password: String?, error: inout String?){

        enum ErrorMessage: String {
            case noName = "Name cannot be empty"
            case noLastName = "Last name cannot be empty"
            case noEmail = "Email cannot be empty"
            case noPassword = "Password cannot be empty"
        }

        if name == "" {
            error = ErrorMessage.noName.rawValue
        }
    }
}

通话

vm.errorMessage(name: name, lastName: lastName, email: email, password: password, error: &nameErrLbl.text)

这里也是一些参考链接

When to use inout parameters?