Ios 为什么我在测试密码验证时没有收到错误?

Ios 为什么我在测试密码验证时没有收到错误?,ios,swift,regex,validation,google-cloud-firestore,Ios,Swift,Regex,Validation,Google Cloud Firestore,正如您可能通过这个问题了解到的,我对iOS/编程一无所知:我正在尝试实现密码验证,其中用户输入必须至少8个字符,包含1个大写字母、1个小写字母、1个数字和1个特殊字符。我决定在UIViewController上使用一个正则表达式和一个扩展来实现这一点我在某个地方读到,我必须将其包含在我的“SignUpViewController”范围之外(不确定为什么)我就是这么做的数据库确实有开放的读/写规则,因为我仍在进行测试,这就是它不检查此验证并每次注册用户的原因吗?请帮忙 代码如下: import U

正如您可能通过这个问题了解到的,我对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)
    }
}
2014年12月更新:
我通过添加密码和电子邮件验证扩展来编辑原始帖子。我使用UITextField上的扩展添加了密码验证。然而,当我尝试对电子邮件执行同样的操作时,我会收到编译错误。这是为什么?

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

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

然后还需要调用验证:

@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
    }
...

您正在使用
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)
}

此格式按预期运行。谢谢

哪里叫
isValidPassword()
?另外,奇怪的是,您确实使用
评估(使用:self)
,但是
self
UIViewController
,而不是
字符串。您是指
扩展字符串{}
,在这种情况下,
self
是正确的,还是
isValidPassword(ustring:String)->Bool{…return…evaluate(with:String)}
?我看不到您在任何地方调用isValidPassword()。您还需要在其中传递一个字符串参数。您和David都提到没有调用该函数(新手错误!)。目前我正在使用扩展UITextField的方法,因为使用传递字符串的函数会给我带来大量错误@LarmeI我现在正在调用containsValidPassword(),你能帮我解释一下为什么当我尝试传递字符串参数时,会出现这么多编译错误吗@你能帮我理解为什么当我试图在func中传递字符串参数时,会出现这么多编译错误吗?这就是为什么我一直在使用UITextField@NivI上的扩展时,let password丢失了一个guard语句。按预期运行!错误消失了!可能会使用协议方法,而@NivI通过添加密码和电子邮件验证扩展来编辑原始帖子。我使用UITextField上的扩展添加了密码验证。然而,当我尝试对电子邮件做同样的操作时,我得到了编译错误。为什么会这样@Dávid Pásztor@CadenJoe你错过了<代码>卫士<代码> >代码>让密码…<代码> @ CadenJoe。如果你发现任何有帮助的答案,你应该考虑把其中的一个标记为被接受的答案。
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)
}
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)
    }
}