简体   繁体   中英

Error Domain=NSCocoaErrorDomain Code=3840 “No value.” when comparing two values. PHP, JSON and Swift

I'm trying to get information from a mysql database into an app using swift. My problem is, what I think, whenever I compare (using a if state) a value to a value from the database I get the error message:

Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}

That is also when ever I compare the value just using an if state looking like this (for example, I will post the whole code later):

$input = $_POST["inputFromUser"];
$resultValue = array();

if($input = "value"){
$resultValue["status"] = "Correct";
echo json_encode($resultValue);
}else{
$resultValue["status"] = "The input do not match";
echo json_encode($resultValue);
}

My conclusion is that whenever the php code compare the values it does something, I don't know. Because when I just get the post and send that value back, example:

$input = $_POST["inputFromUser"];

$resultValue = array();

$resultValue["status"] = $input;
echo json_encode($resultValue);

It sends back the same input I sent to the server.

Here is my code, both Swift and php.

Swift:

import UIKit

class loginView: UIViewController {

    @IBOutlet weak var userUsernameTextField: UITextField!
    @IBOutlet weak var userPasswordTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func loginButtonClicked(sender: AnyObject) {

        let userUsername = userUsernameTextField.text
        let userPassword = userPasswordTextField.text

        if(userUsername!.isEmpty || userPassword!.isEmpty){

            displayAlertMessage("All fields are required!")
            return;
        }

        let hiURL = NSURL(string: "http://testdomaincom/AppLogin/login.php")
        let request = NSMutableURLRequest(URL: hiURL!)
        request.HTTPMethod = "POST"

        let postString = "username=\(userUsername)&password=\(userPassword)"

        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in

            if error != nil {
                print("error=\(error)")
                return
            }

            do {
                let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary

            if let parseJSON = json {
                let resultValue:String = parseJSON["status"] as! String!
                print("result: \(resultValue)")

                if(resultValue=="Success") {

                    NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLoggedIn")
                    NSUserDefaults.standardUserDefaults().synchronize()

                    self.dismissViewControllerAnimated(true, completion: nil)
                }
            }
            }catch{
                print(error)
            }
        }

        task.resume()

    }

    func displayAlertMessage(userMessage:String) {
        let alert = UIAlertController(title: "Alert!", message: userMessage, preferredStyle: UIAlertControllerStyle.Alert)

        let okAction = UIAlertAction(title: "Ok!", style: UIAlertActionStyle.Default, handler:nil)

        alert.addAction(okAction)

        self.presentViewController(alert, animated: true, completion: nil)
    }
}

PHP:

//$user = "1";
//$pass = "2";

$user = $_POST["username"];
$pass = $_POST["password"];

//I know that this is not the best way to connect to mysql, but it will do for now just when I'm testing this things out. $servername = 'server'; $username = 'username'; $password = 'password'; $dbname = 'database';

    $conn = new mysqli($servername, $username, $password, $dbname);
    if ($conn->connect_error) {
        die('Connection failed: ' . $conn->connect_error);
    }

$sql = "SELECT * FROM AppLogin WHERE Username = '".$user."' AND Password = '".$pass."' ";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    $resultValue["status"] = "Yeah!";
    echo json_encode($resultValue);
}else{
    $resultValue["status"] = "No!";
    echo json_encode($resultValue);
?>

I have no idea what is causing this problem, maybe it is the swift code (took it from a tutorial, new to Json) or the php.

Albin.

My guess is that you're submitting the username and password values as optional a because you're not unwrapping them when you get your values. So set a breakpoint when you get the username and password and make sure they're not optional because swift will pass optional variables to php which will result in seemingly innocuous bugs like this one.

EDIT For Clarity:

Since you don't seem to know anything about optionals, I would recommend the Swift Programming Guide to try and at least get a basic understanding of them, since they are paramount to any development in swift. What an optional means is that there's no guarantee the value will exist when a variable is accessed, so in cases where you have optional values you have to check them to see if they exist, and if they do, then you can safely unwrap them. So in your case, the text from a text field can always be unwrapped because the API guarantees that it won't be nil, and will at least be an empty string. Thus, in these lines you're left with optional variables:

let userUsername = userUsernameTextField.text
let userPassword = userPasswordTextField.text

If you were to option click the variable name in Xcode it's type would be String? because you haven't unwrapped it. When that's the case, when you pass this to your PHP service, the value being passed is actually username=Optional("TheUsername")&password=Optional("ThePassword") which is why you're not getting anything back from your database. So, in order to get a non-optional value, you will have to force unwrap your optional values using the ! operator. So it would then be,

let userUsername = userUsernameTextField.text!
let userPassword = userPasswordTextField.text!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM