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

Swift:如何判断MSSQL返回数组中是否包含用户输入密码

iOS MSSQL登录密码验证:代码问题分析与优化方案

嘿,我看你正在实现一个从MSSQL服务器验证密码的登录功能,当前代码里有几个关键问题会导致你的验证逻辑失效,甚至可能引发崩溃,下面我帮你拆解问题并给出优化后的完整代码:

你当前代码的核心问题

1. 完全错误的密码匹配逻辑

你现在用newArrayPassword == self.eMailPassword来判断密码是否存在,这是把单元素数组和包含100条数据的数组直接做全等比较——只有当eMailPassword里刚好只有一个元素,而且和newArrayPassword的元素完全相同时才会返回true,这完全不符合“检查加密密码是否存在于数组中”的需求。

2. 低效且混乱的循环判断

你在遍历查询结果的每一行时,每添加一个密码就做一次判断,不仅重复操作浪费性能,而且逻辑顺序也不对——应该等所有密码都加载到数组后,再做一次统一的存在性检查。

3. 强制解包的崩溃风险

代码里多次用!强制解包可选值(比如password!、email!),如果用户没输入邮箱/密码,或者MD5加密返回nil,你的App会直接崩溃,这在生产环境是绝对不能出现的。

4. 线程安全问题

SQLClient的回调是在后台线程执行的,如果你后续要做UI操作(比如跳转页面、弹出提示),直接在回调里操作会导致UI异常,必须切回主线程。


优化后的完整代码

@IBAction func loginButtonTouchUpInside(_ sender: AnyObject) { 
    // 1. 安全处理用户输入:确保邮箱和密码非空,避免强制解包崩溃
    guard let email = loginEmailInputView.textFieldView.text, !email.trimmingCharacters(in: .whitespaces).isEmpty,
          let password = loginPasswordInputView.textFieldView.text, !password.trimmingCharacters(in: .whitespaces).isEmpty else {
        // 这里可以替换成UI提示,比如弹个Alert告诉用户输入完整信息
        print("请输入有效的邮箱和密码")
        return
    }
    
    // 2. 安全处理MD5加密:避免加密失败导致的崩溃
    guard let md5EncryptedPassword = MD5(password) else {
        print("密码加密失败,请重试")
        return
    }
    
    let targetPassword = md5EncryptedPassword
    print("待验证的加密密码: \(targetPassword)")
    
    // 3. 连接MSSQL服务器
    let client = SQLClient.sharedInstance()! 
    client.connect("asd", username: "asd", password: "asd", database: "asd") { [weak self] success in
        guard success else {
            print("数据库连接失败,请检查服务器配置")
            return
        }
        
        // 4. 执行密码查询
        client.execute("SELECT form_sifre FROM uasd", completion: { results in
            // 确保无论结果如何,都会断开数据库连接
            defer {
                client.disconnect()
            }
            
            // 安全解析查询结果
            guard let results = results as? [[[String:AnyObject]]] else {
                print("查询结果解析失败")
                return
            }
            
            // 5. 提取所有存储的密码到数组
            var storedPasswords = [String]()
            for table in results {
                for row in table {
                    for (_, value) in row {
                        if let passwordStr = value as? String {
                            storedPasswords.append(passwordStr)
                        }
                    }
                }
            }
            
            print("共加载 \(storedPasswords.count) 条密码数据")
            
            // 6. 检查目标密码是否存在
            let isPasswordValid = storedPasswords.contains(targetPassword)
            
            // 7. 切回主线程处理UI逻辑(必须做!iOS要求UI操作在主线程)
            DispatchQueue.main.async { [weak self] in
                if isPasswordValid {
                    print("密码验证成功!执行登录逻辑")
                    // 这里写登录成功的操作,比如跳转到主页面:
                    // self?.navigationController?.pushViewController(MainViewController(), animated: true)
                } else {
                    print("密码验证失败,请重新输入")
                    // 这里可以弹Alert提示用户密码错误
                }
            }
        })
    }
}

关键优化点说明

  • 安全的可选值处理:用guard let替代强制解包,同时添加了空格过滤,避免用户输入空字符就提交。
  • 正确的存在性判断:用数组的contains(_:)方法直接检查目标密码是否在存储的密码数组中,逻辑简单准确。
  • 高效的数据处理:先把所有查询到的密码一次性存入数组,再做一次检查,避免循环内重复判断的冗余操作。
  • 线程安全:用DispatchQueue.main.async切回主线程处理UI操作,完全符合iOS的线程规范。
  • 资源安全:用defer语句确保数据库连接一定会断开,避免资源泄漏。
  • 避免循环引用:在闭包中使用[weak self],防止内存泄漏问题。

内容的提问来源于stack exchange,提问作者SH Yazılım Geliştirme

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:02:34