Reputation: 11
I am trying to switch the LogInViewController
to the homescreen by using a segue with an identifier after selecting a key from the json response I am getting back from my database. I get no errors however there is a warning that says
"Cast from 'String?' to unrelated type '[String : String]' always fails"
which I believe is the problem.
The log after clicking the login button says this:
"Result: SUCCESS
{"status":true,"message":"Successful Login"}
{"user":{"userID":3,"email":"becky1","Final-Score":1,"Game-Reminder":1,"Stat-Update":0,"Game-Start":0}}"
My full code:
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")
}
}
}
}
}
Upvotes: 1
Views: 6602
Reputation: 2561
There are plenty of ways to cast an optional string into a dictionary.
You can use the native 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")
}
}
Upvotes: 0
Reputation: 27211
The problem is that response.result.value
has got optional String
type. But you tries to cast is as Dictionary of [String: String]
here
if let result = response.result.value as? [String:String] {
This code checks it safely but the cast obviously fails. To resolve this issue you have to parse the incode string as json object in order to retrieve the data.
Swift 4 uses Codable
to do this work. Documentation or use Alamofire API which does the same work: this method responseJSON
Upvotes: 1