【问题标题】:Cast from 'String?' to unrelated type '[String : String]' always fails从“字符串?”到不相关的类型 '[String : String]' 总是失败
【发布时间】:2019-03-07 20:09:12
【问题描述】:

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

“从‘字符串’转换?到不相关的类型 '[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")

                    }



}
}
}



}

【问题讨论】:

  • 不要为repost about the same issue创建新帐户。只需编辑原始问题。
  • 我投票结束这个问题作为题外话,因为重复:stackoverflow.com/questions/55033970/…
  • 既然这里有一个合理的答案,@BookOfZeus,而且这个问题写得更好,我们应该更喜欢在另一个方向上结束。 (不过,不支持转发,这是错误的。)
  • @JoshCaswell 好点+1

标签: swift


【解决方案1】:

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

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

这段代码安全地检查了它,但强制转换显然失败了。 要解决此问题,您必须将 incode 字符串解析为 json 对象才能检索数据。

Swift 4 使用Codable 来完成这项工作。 Documentation 或使用做同样工作的 Alamofire API:此方法 responseJSON

【讨论】:

    【解决方案2】:

    有很多方法可以将可选字符串转换为字典。

    可以使用原生的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")
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-20
      • 1970-01-01
      • 1970-01-01
      • 2016-09-17
      • 1970-01-01
      相关资源
      最近更新 更多