从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.
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")