Humfeld
Humfeld

Reputation: 71

POST data via HTTPS to a Webserver using Swift and php

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

Answers (3)

H&#233;ctor Ocampo
H&#233;ctor Ocampo

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

Humfeld
Humfeld

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

Cedan Misquith
Cedan Misquith

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

Related Questions