从XCode的MySQL服务器查询

从XCode的MySQL服务器查询

问题描述:

I am building a simple login with password application using a MySQL Server and PHP files uploaded to a FTP. I have been trying many different ways to get the connection to work on Simulator but to no avail so far. I am using Swift 3.0 and XCode 8.3.2. Somewhere I have made a mistake but I have no idea where! Also I have set the Allow Arbitrary Loads to YES in the info.plist. Any help is appreciated.

In many tutorials I have seen I have seen this popup that I never have gotten. Pop up in tutorial I don't ever get

Simulator image #1

Simulator image #2

In my Login.swift

import UIKit

class Login: UITableViewController {
    @IBOutlet weak var txtUsername: UITextField!
    @IBOutlet weak var txtPassword: UITextField!
    @IBOutlet weak var loginView: UIButton!
    @IBOutlet weak var btnPasswordView: UIButton!
    var passwordString:String!
    var usernameString:String!

    override func viewDidLoad() {
        super.viewDidLoad()
        passwordViewConfig()

    }

    //Function PasswordView.
    func passwordViewConfig() {
        txtPassword.isSecureTextEntry = true
        btnPasswordView.setImage(UIImage(named: "EyeClosedIcon"), for: UIControlState.normal)


    }
    //Action change image PasswordView
    @IBAction func btnPasswordViewAction(_ sender: Any) {
        passwordString = txtPassword.text
        if btnPasswordView.currentImage!.isEqual(UIImage(named: "EyeClosedIcon")) {
            btnPasswordView.setImage(UIImage(named: "EyeOpenIcon"), for: UIControlState.normal)
            txtPassword.isSecureTextEntry = false
            txtPassword.text = nil
            txtPassword.text = passwordString
        } else {
            btnPasswordView.setImage(UIImage(named: "EyeClosedIcon"), for: UIControlState.normal)
            txtPassword.isSecureTextEntry = true
            txtPassword.text = passwordString
        }

    }
    //Redirect select cell to textField
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.section == 0 && indexPath.row == 0 {
            txtUsername.becomeFirstResponder()
        }

        if indexPath.section == 0 && indexPath.row == 1 {
            txtPassword.becomeFirstResponder()
        }
    }
    //Function config Return key
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        if textField == txtUsername {
            textField.resignFirstResponder()
            txtPassword.becomeFirstResponder()
        }
        if textField == txtPassword {
            usernameString = txtUsername.text
            passwordString = txtPassword.text
            if usernameString.isEmpty || passwordString.isEmpty {
                textField.resignFirstResponder()
                txtUsername.becomeFirstResponder()
            } else {
                loginAction(self)
            }
        }
        return true
        }

    //Function config background image login button
    func loginViewConfig() {


    }

    @IBAction func loginAction(_ sender: Any) {
        usernameString = txtUsername.text
        passwordString = txtPassword.text
        if usernameString.isEmpty || passwordString.isEmpty {
            let alertAction:UIAlertAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.default, handler: { (alert) -> Void in
                self.txtUsername.becomeFirstResponder()
            })
            alertView(title: "Error !", message: "Please fill in all fields", alertStyle: UIAlertControllerStyle.alert, alertAction: alertAction)
        } else {
            queryToServerLogin()
        }

    }

    func queryToServerLogin() {
        let url:String = "here is URL to my login.php file"
        /*
        $username = htmlentities($_GET['username']);
        $password = md5(htmlentities($_GET['username']));
        */
        let postString:String = "username=\(usernameString)&password=\(passwordString)"
        print ("username=\(usernameString!)&password=\(passwordString!)")

        self.queryToServer(urlSource: url, postString: postString) { (dataResult, errorResult) -> () in
            if errorResult != nil {
                let alertAction:UIAlertAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.default, handler: nil)
                self.alertView(title: "Error !", message: "Could not connect to server", alertStyle: UIAlertControllerStyle.alert, alertAction: alertAction)
                } else {
                self.extractDataWithNSDictionary(data: dataResult! as NSData, result: { (statusResult, messageResult, errorResult) -> () in
                    if errorResult !== nil {
                        print(errorResult as Any)
                        let alertAction:UIAlertAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.default, handler: nil)
                        self.alertView(title: "Error !", message: "Could not query to server.", alertStyle: UIAlertControllerStyle.alert, alertAction: alertAction)
                    } else {
                        if statusResult == "success" {
                            let alertAction:UIAlertAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.default, handler: nil)
                            self.alertView(title: "Success !", message: messageResult!, alertStyle: UIAlertControllerStyle.alert, alertAction: alertAction)
                            } else {
                                if statusResult == "success" {
                                    let alertAction:UIAlertAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.default, handler: nil)
                                    self.alertView(title: "Error !", message: messageResult!, alertStyle: UIAlertControllerStyle.alert, alertAction: alertAction)
                            }
                      }
                }
            }

        )}
    }
}
}

In my Extensions.swift

import Foundation
import UIKit
extension UIViewController {
    func makeImageViewWithColor(_ color: UIColor) -> UIImage {
        let rect: CGRect = CGRect (x: 0, y: 0, width: 1, height: 1)
        color.setFill()
        UIRectFill(rect)
        let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
    //Function Alert View
    func alertView(title:String, message:String, alertStyle:UIAlertControllerStyle, alertAction:UIAlertAction) {
        let alert:UIAlertController = UIAlertController(title: title, message: message, preferredStyle: alertStyle)
        alert.addAction(alertAction)
        self.present(alert, animated: true, completion: nil)
    }

    //Function query to server
    func queryToServer(urlSource:String, postString:String, result:@escaping (Data?, Error?) -> ()) {
        let url = URL(string: urlSource)!
        var request = URLRequest (url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10)
        request.httpMethod = "POST";
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = postString.data(using: .utf8)
        let session = URLSession.shared
        session.dataTask(with: request) { (data, response, error) in
            DispatchQueue.main.async {
                result(data, error)
            }
            }.resume()
        }

        //Function extract data
        func extractDataWithNSDictionary(data:NSData, result:(_ statusResult:String?, _ messageResult:String?, _ errorResult:NSError?) -> ()){
            var json:NSDictionary!
            var errorParse:NSError!
            do {
            json = try JSONSerialization.jsonObject(with: data as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
        } catch let error as NSError {
            errorParse = error
            json = nil
        }
        if errorParse != nil {
            result(nil, nil, errorParse)
        } else {
            let resultStatus:String = json["status"] as! String
            let resultMessage:String = json["message"] as! String
            result(resultStatus, resultMessage, nil)
    }
}

}

Then in my FTP root I have a MySQL.ini file which was not working

[section]
dbhost = mysql url
dbuser = username
dbpass = password
dbname = database name

Also a mysql.php

<?php

class mysql
{
    var $dbhost = null;
    var $dbuser = null;
    var $dbpass = null;
    var $dbname = null;
    var $conn = null;
    var $result = null;
    function _construct ()
    {
        $mysqlfile = parse_ini_file('MySQL.ini');
        $this->dbhost = $mysqlfile['dbhost'];
        $this->dbuser = $mysqlfile['dbuser'];
        $this->dbpass = $mysqlfile['dbpass'];
        $this->dbname = $mysqlfile['dbname'];

    }
    //Function connect to sql
    public function connection() {
        //$this->conn = new mysqli($this->dbhost, $this->dbuser, $this->dbpass, $this->dbname);
        $this->conn = new mysqli('mysql url', 'username', 'password', 'database name');
        if (mysqli_connect_error()){
            return false;
        }
        mysqli_set_charset($this->conn, 'utf8');
        return true;
    }
    //Function close sql
    public function closeConecttion() {
        if ($this->conn !=null) {
            mysqli_close($this->conn);
        }
    }

    //function check username does not exits
    public function checkUsername($username) {
        $sql = "SELECT authentication_username FROM time_employee WHERE authentication_username = '$username'";
        $this->result = mysqli_query($this->conn, $sql);
        if (mysqli_num_rows($this->result) <= 0 ) {
            return false;
        }
        return true;
    }

    //function check password username
    public function checkPasswordUsername($username, $password) {
        $sql = "SELECT authentication_username, authentication_password FROM time_employee WHERE authentication_username = '$username'";
        $this->result = mysqli_query($this->conn, $sql);
        $row = mysqli_fetch_array($this->result);
        if ($row['password'] != $password) {
            return false;
        }
        return true;
    }

}

And a login.php

<?php

include_once('mysql.php');
$mysql = new mysql();
$username = htmlentities($_REQUEST['username']);
$password = md5(htmlentities($_REQUEST['password']));
$resultValue = array();
//Function check connect to database
if ($mysql->connection()) {
    //Function check username exist
    //if !mysql->checkUsername($username) return false
    if(!$mysql->checkUsername($username)) {
        $resultValue['status'] = "error";
        $resultValue['message'] = "username does not exist";
        echo json_encode($resultValue);
    } else {
        //Function check password
        //If !$mysql->checkPasswordUsername($username, $password) return false
        if (!$mysql->checkPasswordUsername($username, $password)) {
            $resultValue['status'] = "error";
            $resultValue['message'] = "Incorrect password";
            echo json_encode($resultValue);
        } else {
            $resultValue['status'] = "success";
            $resultValue['message'] = "Logged in successfully";
            echo json_encode($resultValue);
        }
    }
} else {
    $resultValue['status'] = "error";
    $resultValue['message'] = "could not connect to database";
    echo json_encode($resultValue);
}
?>
<?php exit; ?>

I also noticed you are sending your post data in the form username=...&password=... But in queryToServer() you have the line

request.addValue("application/json", forHTTPHeaderField: "Content-Type")

You are saying the data you have attached is json when it is not. Try this instead.

 request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")