Swift 从';字符串?';不相关类型';[字符串:字符串]';总是失败

Swift 从';字符串?';不相关类型';[字符串:字符串]';总是失败,swift,Swift,在从数据库返回的json响应中选择一个键后,我尝试使用带有标识符的segue将LogInViewController切换到主屏幕。我没有收到任何错误,但是有一个警告说 “从'String'转换为不相关的类型'[String:String]'总是失败” 我相信这就是问题所在 单击“登录”按钮后的日志显示: "Result: SUCCESS {"status":true,"message":"Successful Login"} {"user":{"userID":3,"email":"beck

在从数据库返回的json响应中选择一个键后,我尝试使用带有标识符的segue将
LogInViewController
切换到主屏幕。我没有收到任何错误,但是有一个警告说

“从'String'转换为不相关的类型'[String:String]'总是失败”

我相信这就是问题所在

单击“登录”按钮后的日志显示:

"Result: SUCCESS
{"status":true,"message":"Successful Login"}  
{"user":{"userID":3,"email":"becky1","Final-Score":1,"Game-Reminder":1,"Stat-Update":0,"Game-Start":0}}"
我的完整代码:

import UIKit
import Alamofire
import GoogleSignIn
import SwiftyJSON

class LogInViewController: UIViewController,GIDSignInUIDelegate, GIDSignInDelegate {
    @IBOutlet weak var lblTitle: UILabel!
    @IBOutlet weak var btnGoogleSignIn:UIButton!

    //you can get the ip using ifconfig command in terminal
    let URL_USER_LOGIN = "http://cgi.sice.indiana.edu/~team58/login.php"

    let defaultValues = UserDefaults.standard

    @IBOutlet weak var textFieldEmail: UITextField!
    @IBOutlet weak var textFieldPassword: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()
        ///Google Sign in////
        btnGoogleSignIn.addTarget(self, action: #selector(signinUserUsingGoogle(_:)), for: .touchUpInside)
        // Do any additional setup after loading the view, typically from a nib.

    }

    @objc func signinUserUsingGoogle(_ sender: UIButton) {
        if btnGoogleSignIn.title(for: .normal) == "Sign Out" {
            GIDSignIn.sharedInstance().signOut()
            lblTitle.text = ""
            btnGoogleSignIn.setTitle("Sign in Google", for: .normal)
        } else {

            GIDSignIn.sharedInstance().delegate = self
            GIDSignIn.sharedInstance().uiDelegate = self
            GIDSignIn.sharedInstance().signIn()



        }

    }

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
        if let error = error {
            print("We have error signing in user == \(error.localizedDescription)")
        } else {
            performSegue(withIdentifier: "popOutNoteExpanded", sender: self)
            if let gmailUser = user {
                lblTitle.text = "You are signed in using id \(gmailUser.profile.email)"
                btnGoogleSignIn.setTitle("Sign Out", for: .normal)

                /// end google sign in ///
            }
        }
    }


    @IBAction func LoginButton(_ sender: UIButton) {
        let parameters: Parameters=[
            "email":textFieldEmail.text!,
            "password":textFieldPassword.text!
        ]

        //making a post request
        Alamofire.request(URL_USER_LOGIN, method: .post, parameters: parameters).responseString
            {
                response in

//                print("Request: \(String(describing: response.request))")   // original url request
//                print("Response: \(String(describing: response.response))") // http url response
                print("Result: \(response.result)")
                print(response.result.value!)

//
//                //self.ResponseLabel.text = "Result: \(response.result)"

                if let result = response.result.value as? [String:String] {



                    //if there is no error

//                    if result["SUCCESS"] {

                    if result["message"] == "Succesful Login" {



                        //getting the user from response

                        //getting user values - not neccesary
                        if let userEmail = result["email"] {
                           self.defaultValues.set(userEmail, forKey: "email")
                        }
                        if let userPassword = result["password"] {
                          self.defaultValues.set(userPassword, forKey: "password")
                        }
                        self.performSegue(withIdentifier: "popOutNoteExpanded", sender: self)




//
                        } else  {
                        //error message in case of invalid credential
                      // original url request
//                        print("Response: \(String(describing: response.response))") // http url response

                        print("invalid credentials")

                    }



}
}
}



}

问题是
response.result.value
具有可选的
String
类型。但您尝试在此处将其转换为
[String:String]
的字典

 if let result = response.result.value as? [String:String] {
这段代码安全地检查了它,但是cast显然失败了。 要解决这个问题,您必须将incode字符串解析为json对象,以便检索数据


Swift 4使用
Codable
来完成这项工作。或者使用Alamofire API,它也可以完成同样的工作:这个方法
responseJSON

有很多方法可以将可选字符串强制转换到字典中

您可以使用本机
JSONSerialization

guard let text = response.result.value as? String else { return } 
    if let data = text.data(using: String.Encoding.utf8) {
        do {
            let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:String]
            print(json) // safely use json
        } catch {
            print("Error")
        }
    }

不要为创建新帐户。只需编辑原始问题。我投票将这个问题作为离题题结束,因为重复:既然这里有一个合理的答案,@BookOfZeus,而且这个问题写得更好,我们应该选择另一个方向结束。(不过,不是为了支持重新发布,这是错误的。)@JoshCaswell好观点+1