【问题标题】:Why am I NOT getting an error when I test password validation?为什么我在测试密码验证时没有收到错误消息?
【发布时间】:2018-12-05 15:50:19
【问题描述】:

正如您可能通过这个问题所说的那样,我是 iOS/编程新手:我正在尝试实现密码验证,其中用户输入必须至少为 8 个字符,包含 1 个大写字母,1小写字母、1 个数字和 1 个特殊字符。我决定在 UIViewController 上使用正则表达式和扩展来执行此操作。 我在某处读到我必须将其包含在我的“SignUpViewController”范围之外(不知道为什么),这就是我所做的。 数据库确实有开放的读/写规则,因为我仍在测试东西所以它不检查此验证并每次都注册用户的原因是什么?请帮忙

下面是代码:

import UIKit
import Firebase



class SignUpViewController: UIViewController {

    //Outlets
    @IBOutlet weak var firstNameText: UITextField!
    @IBOutlet weak var lastNameText: UITextField!
    @IBOutlet weak var emailText: UITextField!
    @IBOutlet weak var passwordText: UITextField!
    @IBOutlet weak var signUpButton: UIButton!


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


    @IBAction func signUpButtonTapped(_ sender: Any) {
        guard let firstName = firstNameText.text,
            let lastName = lastNameText.text,
            let email = emailText.text else { return }
            guard emailText.containsValidEmail() else {
            print("Invalid email. Please try again.")
            return
        }
            let password = passwordText.text else { return }
            guard passwordText.containsValidPassword() else {
            print("Invalid password. Please try again.")
            return
        }

        Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
            if let error = error {
                debugPrint("Error creating user: \(error.localizedDescription)")
            }
            let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
            changeRequest?.displayName = firstName
            changeRequest?.commitChanges(completion: { (error) in
                if let error = error {
                    debugPrint(error.localizedDescription)
                }
            })
            guard let userId = authResult?.user else { return }
            let userData: [String: Any] = [
                "firstName" : "",
                "lastName" : "",
                "User ID" : userId,
                "dateCreated" : FieldValue.serverTimestamp(),
                ]
            let db = Firestore.firestore()
            db.collection("users").document("one").setData(userData) { err in
                if let err = err {
                    print("Error writing document: \(err)")
                } else {
                    print("Document successfully written!")
                }
            }
        }
    }
}
public extension UITextField {
    func containsValidPassword() -> Bool {
        let passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[d$@$!%*?&#])[A-Za-z\\dd$@$!%*?&#]{8,}"
        return NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: self.text)
    }
}
public extension UITextField {
    func containsValidEmail() -> Bool {
    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: self.text)
    }
}

12/14 更新: 我通过添加密码和电子邮件验证的扩展来编辑原始帖子。我通过在 UITextField 上使用扩展来添加密码验证。但是,当我尝试对电子邮件执行相同操作时,会出现编译错误。这是为什么呢?

【问题讨论】:

  • 哪里叫isValidPassword()?此外,奇怪的是,您使用evaluate(with: self),但selfUIViewController,而不是String。你的意思是extension String{},在这种情况下self是正确的,还是isValidPassword(_ string: String) -> Bool { ... return ... evaluate(with: string) }
  • 我没有看到你在任何地方调用 isValidPassword()。您还需要在其中传递一个字符串参数。
  • 你和大卫都提到不调用函数(新手错误!)。目前我正在使用扩展 UITextField 的方法,因为使用传递字符串的函数会给我带来大量错误@Larme
  • 我现在正在调用 containsValidPassword(),您能帮忙解释一下为什么当我尝试传递字符串参数时,会出现这么多编译错误吗? @敢

标签: ios swift regex validation google-cloud-firestore


【解决方案1】:

首先,您没有在代码中的任何位置调用isValidPassword 函数。其次,如果你真的调用它,它会导致运行时异常,因为你会尝试将 UIViewController 实例传递给 NSPredicate 以匹配正则表达式。

您应该在UITextField 上定义isValidPassword 并验证其text 属性。 (在这种情况下,我还将函数重命名为 containsValidPassword,因为 UITextField 不是密码,它只包含密码字符串。)

extension UITextField {
    func containsValidPassword() -> Bool {
        let passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[d$@$!%*?&#])[A-Za-z\\dd$@$!%*?&#]{8,}"
        return NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: self.text)
    }
}

那你还需要调用验证:

@IBAction func signUpButtonTapped(_ sender: Any) {
    guard let firstName = firstNameText.text,
        let lastName = lastNameText.text,
        let email = emailText.text,
        let password = passwordText.text else { return }
    guard passwordText.containsValidPassword() else { 
        // Let the user know that their pwd is incorrect
        return
    }
...

【讨论】:

  • 我通过添加密码和电子邮件验证的扩展来编辑原始帖子。我通过在 UITextField 上使用扩展来添加密码验证。但是,当我尝试对电子邮件执行相同操作时,我得到了编译错误。为什么是这样? @Dávid Pásztor
  • @CadenJoe 你在let password...之前错过了guard
  • @CadenJoe 如果您发现任何答案有帮助,您应该考虑将其中一个标记为已接受的答案
【解决方案2】:

您正在使用self 评估您的谓词,其中self 的类型为UIViewController(这就是您要扩展的),您可能打算改为扩展String

extension String {
    func isValidPassword() -> Bool {
        let passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[d$@$!%*?&#])[A-Za-z\\dd$@$!%*?&#]{8,}"
        return NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: self)
    }
}

用法:

let isValidPassword = "something".isValidPassword()

实际上我不确定扩展是否适合这种情况,我建议您在 SignUpViewController- 中创建一个简单的函数-

func isValidPassword(password: String) -> Bool {
    let passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[d$@$!%*?&#])[A-Za-z\\dd$@$!%*?&#]{8,}"
    return NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: password)
}

或者如果你想更具体-

func isValidPassword() -> Bool{
    guard let password = passwordText.text else { return false }

    let passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[d$@$!%*?&#])[A-Za-z\\dd$@$!%*?&#]{8,}"
    return NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: password)
}

【讨论】:

  • 您能帮我理解为什么当我尝试在 func 中传递字符串参数时,会出现这么多编译错误吗?这就是为什么我一直在 UITextField @Niv 上使用扩展
  • 我错过了 let 密码的保护声明。按预期运行!错误消失了!可能会使用协议方法而不是@Niv
【解决方案3】:
import UIKit
import Firebase



class SignUpViewController: UIViewController {

    //Outlets
    @IBOutlet weak var firstNameText: UITextField!
    @IBOutlet weak var lastNameText: UITextField!
    @IBOutlet weak var emailText: UITextField!
    @IBOutlet weak var passwordText: UITextField!
    @IBOutlet weak var signUpButton: UIButton!


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


    @IBAction func signUpButtonTapped(_ sender: Any) {
        guard let firstName = firstNameText.text,
            let lastName = lastNameText.text,
            let email = emailText.text else { return }
            guard emailText.containsValidEmail() else {
            print("Invalid email/password. Please try again.")
            return
        }
            guard let password = passwordText.text else { return }
            guard passwordText.containsValidPassword() else {
            print("Invalid email/password. Please try again.")
            return
        }

        Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
            if let error = error {
                debugPrint("Error creating user: \(error.localizedDescription)")
            }
            let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
            changeRequest?.displayName = firstName
            changeRequest?.commitChanges(completion: { (error) in
                if let error = error {
                    debugPrint(error.localizedDescription)
                }
            })
            guard let userId = authResult?.user else { return }
            let userData: [String: Any] = [
                "firstName" : "",
                "lastName" : "",
                "User ID" : userId,
                "dateCreated" : FieldValue.serverTimestamp(),
                ]
            let db = Firestore.firestore()
            db.collection("users").document("one").setData(userData) { err in
                if let err = err {
                    print("Error writing document: \(err)")
                } else {
                    print("Document successfully written!")
                }
            }
        }
    }
}
public extension UITextField {
    func containsValidPassword() -> Bool {
        let passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[d$@$!%*?&#])[A-Za-z\\dd$@$!%*?&#]{8,}"
        return NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: self.text)
    }
}
public extension UITextField {
    func containsValidEmail() -> Bool {
        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
        return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: self.text)
    }
}

此格式按预期运行。谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 2016-04-24
    • 2011-04-22
    相关资源
    最近更新 更多