Reputation: 71
I want to POST Data in a Textfield via HTTPS to a Webserver using Swift and PHP and tried this Example POST data to a PHP method from Swift, but it is not compatible with PHP7.
Now this is for PHP7 and Swift 4 but i got an empty entry in the MySql Database.
I think thats the PHP-File...
Use Xcode 10.1 Any Solution?
Swift:
import UIKit
class MessageViewController: UIViewController {
@IBOutlet weak var nachricht: UITextField!
@IBAction func submit(_ sender: Any) {
let url = NSURL(string: "http://localhost.com") // localhost MAMP - change to point to your database server
var request = URLRequest(url: url! as URL)
request.httpMethod = "POST"
var dataString = "secretWord=???" // starting POST string with a secretWord
// the POST string has entries separated by &
dataString = dataString + "&nachricht=\(nachricht.text!)" // add items as name and value
// convert the post string to utf8 format
let dataD = dataString.data(using: .utf8) // convert to utf8 string
do {
// the upload task, uploadJob, is defined here
let uploadJob = URLSession.shared.uploadTask(with: request, from: dataD) { data, response, error in
if error != nil {
// display an alert if there is an error inside the DispatchQueue.main.async
DispatchQueue.main.async {
let alert = UIAlertController(title: "Upload Didn't Work?", message: "Looks like the connection to the server didn't work. Do you have Internet access?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
} else {
if let unwrappedData = data {
let returnedData = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue) // Response from web server hosting the database
if returnedData == "1" { // insert into database worked
// display an alert if no error and database insert worked (return = 1) inside the DispatchQueue.main.async
DispatchQueue.main.async {
let alert = UIAlertController(title: "Upload OK?", message: "Looks like the upload and insert into the database worked.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
} else {
// display an alert if an error and database insert didn't worked (return != 1) inside the DispatchQueue.main.async
DispatchQueue.main.async {
let alert = UIAlertController(title: "Upload Didn't Work", message: "Looks like the insert into the database did not worked.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
}
}
uploadJob.resume()
}
}
}
PHP File:
<?php
$secret = $_POST["secretWord"];
if ("???" != $secret) exit; // note the same secret as the app - could be let out if this check is not required. secretWord is not entered by the user and is used to prevent unauthorized access to the database
$nachricht = $_POST['nachricht'];
// POST items should be checked for bad information before being added to the database.
// Create connection
$mysqli=mysqli_connect("localhost","db","db_pass","db_usr"); // localhost, user name, user password, database name
// Check connection
if (mysqli_connect_errno())
{
echo "
Failed to connect to MySQL: " . mysqli_connect_error();
}
$query = "insert into `db` (nachricht) value ('".$nachricht."')";
$result = mysqli_query($mysqli,$query);
echo $result; // sends 1 if insert worked
?>
Upvotes: 0
Views: 912
Reputation: 1
I had the same problem. My solution was to use import MultipartForm and define the form.
let form = MultipartForm(parts: [
MultipartForm.Part(name: "id", value: incidente!.id),
MultipartForm.Part(name: "mensaje", value: txtDescripcion.text!),
MultipartForm.Part(name: "direccion", value: txtDireccion.text!),
MultipartForm.Part(name: "nombre", value: txtNombre.text!),
MultipartForm.Part(name: "telefono", value: txtTelefono.text!),
MultipartForm.Part(name: "email", value: txtEmail.text!),
MultipartForm.Part(name: "latitud", value: StrLatitud),
MultipartForm.Part(name: "longitud", value: StrLongitud),
MultipartForm.Part(name: "token", value: "44fdcv8jf3"),
MultipartForm.Part(name: "imagen64", value: mImagenStr)
])
Then save the image with
file_put_contents($ruta,base64_decode($_POST['imagen64']));
Upvotes: 0
Reputation: 71
This is from Xcode: [MC] Reading from private effective user settings. Session Response: { URL: https://localhost.com/api.php } { Status Code: 200, Headers { Connection = ( "Keep-Alive" ); "Content-Encoding" = ( gzip ); "Content-Length" = ( 21 ); "Content-Type" = ( "text/html; charset=UTF-8" ); Date = ( "Sun, 02 Dec 2018 10:06:45 GMT" ); "Keep-Alive" = ( "timeout=5, max=100" ); Server = ( Apache ); "Strict-Transport-Security" = ( "max-age=31556926" ); Vary = ( "Accept-Encoding" ); } } 2018-12-02 11:10:36.854962+0100 Localhost[2289:36190] [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C1.1:2][0x7f8f76f215b0] get output frames failed, state 8196
There is no entry from the Text field transmitted in the MySql Database.
Upvotes: 0
Reputation: 1154
I do not have much info on the PHP part of your problem. But i would recommend you try using "https://github.com/Alamofire/Alamofire" for all your networking needs as it supports Swift 4 with PHP7. It also reduces the number of lines of code you need to write.
So with Alamofire your POST request would look something like this.
import UIKit
import Alamofire
class MessageViewController: UIViewController {
@IBOutlet weak var nachricht: UITextField!
@IBAction func submit(_ sender: Any) {
let body: Parameters = [
"secretWord":"???",
"nachricht":"\(nachricht.text!)",
]
Alamofire.request("http://localhost.com", method: .post, parameters: body, encoding: JSONEncoding.default).responseJSON { response in
print("Your response from server is: \(response)")
}
}
}
Hope this solves the Swift part of your problem.
EDIT: As requested here is an update. I have implemented your request without using a networking manager (Alamofire)
import UIKit
class MessageViewController: UIViewController {
@IBOutlet weak var nachricht: UITextField!
@IBAction func submit(_ sender: Any) {
// MARK: Preparing json data
let parameters: [String: Any] = [
"secretWord":"???",
"nachricht":"\(nachricht.text!)",
]
//Serialise Parameters to JSON data.
let jsonData = try? JSONSerialization.data(withJSONObject: parameters)
// create post request
let url = URL(string: "http://localhost.com")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print("Session Response: \(String(describing: response!))")
let httpResponse = response as? HTTPURLResponse
let statusCode = httpResponse?.statusCode
if statusCode == 404 {
DispatchQueue.main.async {
// create the alert
let alert = UIAlertController(title: "Server not available", message: "Try again later.", preferredStyle: UIAlertController.Style.alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
}
}else{
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print("Your response from server is: \(responseJSON)")
}
}
}
task.resume()
}
}
Upvotes: 1