I am trying to send a JSON array to the web server. I have looked at several examples online i.e. https://www.youtube.com/watch?v=aTj0ZLha1zE&t and Saving CoreData to a Web Server with Swift 3.0 that have demonstrated how to parse data but I am struggling to achieve this.
Below is my function which should send the data to the server:
func sendRecordToServer() -> [Record] {
let fetchRequest = NSFetchRequest<NSDictionary>(entityName:"Record")
fetchRequest.resultType = .dictionaryResultType
do {
let records = try context.fetch(fetchRequest)
if let jsonData = try? JSONSerialization.data(withJSONObject: records, options: []) {
// jsonData is a byte sequence, to view it you would need to convert to string
print(String(bytes: jsonData, encoding: String.Encoding.utf8))
let URL_SAVE_DATA = URL(string: "http://localhost/api/postdata.php")
let request = NSMutableURLRequest(url: URL_SAVE_DATA!)
request.httpMethod = "POST"
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
guard let data = data, error == nil else {
// check for fundamental networking error
print("error=\(String(describing: error?.localizedDescription))")
return
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
}
} catch {
print("Error fetching data from CoreData")
}
return records
}
After encoding the data to JSON, it prints out like this:
Optional([["record_id": 8EC9C1C9-7DD4-4343-B7CC-E4615FDDA150, "name": John ], ["record_id": 7EEA551D-9432-4737-99FB-6BFCF3A92D21, "name": Fred Smith]])
However as I try parsing it though to the server I get this and nothing get sent to the server:
responseString = Optional("")
Update:
Following up from the comment below here is what my posdata.php looks like:
<?php
//creating response array
$json = file_get_contents('php://input');
//echo $json shoulkd show the json string
$array = json_decode($json, true);
// var_dump($arr) should show the array structure
$response = array();
if($_SERVER['REQUEST_METHOD']=='POST'){
//getting values
$record_id = $_POST['record_id'];
$name = $_POST['name'];
//including the db operation file
require_once '../includes/DbOperation.php';
$db = new DbOperation();
//inserting values
if($db->createTeam($record_id, $name)){
$response['error']=false;
$response['message']='Record added successfully';
}else{
$response['error']=true;
$response['message']='Could not add record';
}
}else{
$response['error']=true;
$response['message']='You are not authorized';
}
echo json_encode($response);
DBOperation:
<?php
class DbOperation
{
private $conn;
//Constructor
function __construct()
{
require_once dirname(__FILE__) . '/Config.php';
require_once dirname(__FILE__) . '/DbConnect.php';
// opening db connection
$db = new DbConnect();
$this->conn = $db->connect();
}
//Function to create a new user
public function createTeam($record_id, $name)
{
$stmt = $this->conn->prepare("INSERT INTO record (record_id, name) values (?, ?)");
$stmt->bind_param("si", $record_id, $name);
$result = $stmt->execute();
$stmt->close();
if ($result) {
return true;
} else {
return false;
}
}
}
Related
I had tried many times in Swift, seem the problem happened in the PHP file. i dont know the data tpye of $revaID correct i get $revaID value from swift, i want to use revaID to delete row from table reservation ,it is auto created.please help
<?php
$host = "127.0.0.1";
$username = "root";
$password = "password";
$dbname = "project";
// Connect to server
$connect=mysqli_connect("127.0.0.1", "root", "password","project")
or die ("Sorry, unable to connect database server");
$revaID = $_POST["revaID"]; ;
$UserID = $_["UserID"];
// Run the query
$query = "DELETE FROM reservation WHERE revaID = '$revaID'";
$result = mysqli_query($connect,$query);
////////////////////ignore///////// //////////////////
if ($result) {
print $result;
print "Suss";
print $revaID;
} else {
print "Failed to delete record!";
print(mysqli_error($connect));}
////////////////// ////////////////// //////////////////
////////////////////ignore////////////////////////
if ($revaID){
set_include_path('/Library/WebServer/Documents/');
$id2 = array();
$id2['revaID'] = $revaID;
// Loop through each row in the result set
$json = json_encode($id2, JSON_NUMERIC_CHECK );
file_put_contents('deleterevaID.php',$json,FILE_USE_INCLUDE_PATH);}
////////////////// //////////////////
mysqli_close($connect);
?>
and this is my swife code, when editingStyle == .delete , i got $revaID.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
let UserID = userinfo[indexPath.row]
// print(UserID)
userinfo.remove(at:indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
// Service.shared.deletePost(revaID:UserID.revaID) { (err) in
// }
let urlStr = "http://localhost/deleteres.php"
if let url = URL(string: urlStr) {
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "DELETE"
let body = "revaID=\(UserID.revaID)"
print("ID:",UserID.revaID)
if let data = body.data(using: .utf8) {
let dataTask = URLSession.shared.uploadTask(with: urlRequest,
from: data, completionHandler: {
data, response, error in
if let error = error{
print("error: \(error.localizedDescription)")
}
// print(UserID.revaID)
//self.refreshBtnClicked(self)
})
dataTask.resume()
}
}
}
}
in a swift file, you are sending data with get method and in a PHP file you are trying to get data with post method.
so instead of this :
$revaID = $_POST["revaID"]; ;
try to get data by get method
$revaID = $_GET["revaID"]; ;
I am able to consume the php endpoint from postman. I try to do the same from angular post, I get this error - Http failure during parsing for. Even though everything looks perfect to me, the problem is surprising. Here is my snippet
php file
<?php
header('Access-Control-Allow-Origin: *');
// check for post
if ($_SERVER['REQUEST_METHOD']=='POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
$conn = new db_CONNECT();
$cone=$conn->con;
//escpae the strings to be inserted to DB
$escapedname = mysqli_real_escape_string($cone, $name);
$escapedemail = mysqli_real_escape_string($cone, $email);
$escapedsubject= mysqli_real_escape_string($cone, $subject);
$escapedmessage = mysqli_real_escape_string($cone, $message);
// mysql inserting a new row
$sql = "INSERT INTO contacts(name, email, subject, message) VALUES ('$escapedname', '$escapedemail', '$escapedsubject', '$escapedmessage')";
// $result= $cone -> query($sql);
// $affected = $cone -> affected_rows;
if (mysqli_query($cone,$sql)) {
echo "Information saved successfully.";
} else {
echo "Not successful";
}
} else {
echo "Some field missing.";
}
?>
here is the angular snippet
saveContactDetails = function () {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
data.append('name', this.contactDeJson.name);
data.append('email', this.contactDeJson.email);
data.append('subject', this.contactDeJson.subject);
data.append('message', this.contactDeJson.message);
this.http
.post('http://localhost:80/'+'api/create_contact.php', data.toString(), {headers: myheader})
Please why am I getting this error
{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://localhost/api/create_contact.php","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://localhost/api/create_contact.php",
I believe the issue is that your angular script is expecting a json response (the default responseType), but not receiving the correct headers or data. In stead of just echoing out your result in php, I would make a function that can handle sending the response. Something like this:
function sendJsonResponse(data, status = 200) {
header('Content-Type: application/json', true, status);
echo json_encode($data);
exit();
}
In stead of of doing this:
echo "Not successful";
You can now do this:
sendJsonResponse("Not successful", 500);
This should give you more valuable information in the frontend. And the response should now be formatted correctly, and no longer produce the parse error in angular that you are getting now.
I believe you are trying to send some query parameters using data variable. You could actually send a JS object as the parameters. Try the following
private saveContactDetails() {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const data = {
'name': this.contactDeJson.name,
'email': this.contactDeJson.email,
'subject': this.contactDeJson.subject,
'message': this.contactDeJson.message
}
this.http.post('http://localhost:80/'+'api/create_contact.php', { params: data }, { headers: myheader })
}
I would like to implement an IOS app via swift 5 to adjust a MySQL database triggered by a PHP script. I try to use the post request to handover the following parameters:
teamName = "Testteam"
teamCount = "member"
After some testing I found out, that parameters are not handover to PHP script (they are empty) and I don't know why.
Swift Code
let URL_SAVE_TEAM ="http://www.mydomain.de/createteam.php"
#IBOutlet weak var textFieldName: UITextField!
#IBOutlet weak var textFieldMember: UITextField!
#IBAction func Login(_ sender: UIButton) {
//created NSURL
let requestURL = NSURL(string: URL_SAVE_TEAM)!
//creating NSMutableURLRequest
let request = NSMutableURLRequest(url: requestURL as URL)
//setting the method to post
request.httpMethod = "POST"
//getting values from text fields
let teamName = textFieldName.text
let memberCount = textFieldMember.text
//creating the post parameter by concatenating the keys and values from text field
//let postParameters = "name="+teamName!+"&member="+memberCount!;
//adding the parameters to request body
request.httpBody = postParameters.data(using: String.Encoding.utf8)
//creating a task to send the post request
let task = URLSession.shared.dataTask(with: request as URLRequest) {
(data, response, error) in
if error != nil {
print("error is \(String(describing: error))")
return
}
do { //parsing the response
let myJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary //converting resonse to NSDictionary
print(myJSON)
//parsing the json
if let parseJSON = myJSON {
//creating a string
var msg : String!
//getting the json response
msg = parseJSON["message"] as! String?
//printing the response
print(msg!)
}
} catch {
print(error)
}
}
//executing the task
task.resume()
}
PHP script on server
<?php
//creating response array
$response = array();
if($_SERVER['REQUEST_METHOD']=='POST'){
//getting values
$teamName = $_GET['name'];
$memberCount = $_GET['member'];
$fp = fopen ('debug.log' , "w"); // Datei öffnen
fwrite ($fp , 'test'); // Dateiinhalt in die Datei schreiben
fwrite ($fp , $teamName); // Dateiinhalt in die Datei schreiben
fwrite ($fp , $memberCount); // Dateiinhalt in die Datei schreiben
fclose ($fp); // Datei schließen
//including the db operation file
require_once '../includes/DbOperation.php';
$db = new DbOperation();
//inserting values
if($db->createTeam($teamName,$memberCount)){
$response['error']=false;
$response['message']='Team added successfully';
}else{
$response['error']=true;
$response['message']='Could not add team';
}
}else{
$response['error']=true;
$response['message']='You are not authorized';
}
echo json_encode($response);
?>
The PHP script is sending the error message (Could not add team) because the variable $teamName and $memberCount are empty. The overall connection to the PHP script seems to work.
You are using POST method, so you should get POST values not GET values:
if($_SERVER['REQUEST_METHOD']=='POST'){
//getting values
$teamName = $_POST['name'];
$memberCount = $_POST['member'];
I am trying to send a JSON object containing username and password info from an iOS app to my server for login. However, it seems like the php code never received the JSON object or decoded it correctly. I have tried many different ways to convert JSON object and send to server, but none of them succeeded. I am coding in swift 2 by the way. Any help? THANKS!
Here is my swift code:
let myUrl = NSURL(string: "myURL");
let request = NSMutableURLRequest(URL: myUrl!);
request.HTTPMethod = "POST";
let params : [String : AnyObject] = ["username": username!, "password": password!];
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type");
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions());
request.HTTPBody = jsonData;
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)! as String
print(jsonString);
print(request.HTTPBody);
} catch {
print(error)
}
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableLeaves) as? NSDictionary
print(response)
if let parseJSON = json {
let resultValue = parseJSON["type"] as? Int
print("result: \(resultValue)")
}
} catch {
print(error)
}
})
task.resume()
And here is my php code:
require("Conn.php");
require("MySQLDao.php");
$fp = fopen("data.txt", "a+");
$data = file_get_contents('php://input');
$json = json_decode($data, false);
$username = $_POST['username'];
$password = $_POST['password'];
fwrite($fp, $data);
fwrite($fp, $json);
fwrite($fp, $username);
fwrite($fp, $password);
fclose($fp);
$returnValue = array();
if (empty($username) || empty($password)) {
$returnValue["status"] = "error";
$returnValue["message"] = "Missing required field";
echo json_encode($returnValue);
return;
}
$dao = new MySQLDao();
$dao->openConnection();
$userType = $dao->passwordAuthentification($username, $password);
if ($userType != null) {
$returnValue["type"] = (int)$userType;
echo json_encode($returnValue);
} else {
$returnValue["type"] = -1;
$returnValue["message"] = "user is not found";
echo json_encode($returnValue);
}
$dao->closeConnection();
I am trying to send data to php and insert it to mysql database but it doesn't seem to work. I have tried sending data to php just to encode it to json and echo it back to swift and it returns a result so it means that the php file received the data. However inserting the data is not working.
swift2 httppost
func post() {
let myUrl = NSURL(string: "http://localhost:8080/json/json.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST"
// Compose a query string
let postString = "firstName=James&lastName=Bond";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil
{
print("error=\(error)")
return
}
// You can print out response object
print("response = \(response)")
// Print out response body
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
//Let’s convert response sent from a server side script to a NSDictionary object:
do{
let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
if let parseJSON = myJSON {
// Now we can access value of First Name by its key
let firstNameValue = parseJSON["firstName"] as? String
print("firstNameValue: \(firstNameValue)")
}
}catch let error as NSError {
print("JSON Error: \(error.localizedDescription)")
}
}
task.resume()
}
json.php
<?php
// Read request parameters
$firstName= $_REQUEST["firstName"];
$lastName = $_REQUEST["lastName"];// Store values in an array
$conn = mysqli("localhost", "root", "root", "notify");
$query = mysqli_query($conn, "INSERT INTO user values('', '$firstName',
'$lastName')");
?>
If having the server just echo the request works, then the problem rests within the server, not the client code. I would suggest adding some error handling in the PHP code:
<?php
// specify that this will return JSON
header('Content-type: application/json');
// open database
$con = mysqli_connect("localhost","user","password","notify");
// Check connection
if (mysqli_connect_errno()) {
echo json_encode(array("success" => false, "message" => mysqli_connect_error(), "sqlerrno" => mysqli_connect_errno()));
exit;
}
// get the parameters
$field1 = mysqli_real_escape_string($con, $_REQUEST["firstName"]);
$field2 = mysqli_real_escape_string($con, $_REQUEST["lastName"]);
// perform the insert
$sql = "INSERT INTO user (first_name, last_name) VALUES ('{$field1}', '{$field2}')";
if (!mysqli_query($con, $sql)) {
$response = array("success" => false, "message" => mysqli_error($con), "sqlerrno" => mysqli_errno($con), "sqlstate" => mysqli_sqlstate($con));
} else {
$response = array("success" => true);
}
echo json_encode($response);
mysqli_close($con);
?>
Notes:
I wouldn't recommend logging in as root.
Make sure you use mysqli_real_escape_string to protect yourself against SQL injection attacks (see point 1).
I don't know if your user table has other fields in it, but if so, you might want to specify the column names in the insert statement. Even if you only have those two columns, it's a good way to "future-proof" your code.
Note, I've changed this to generate JSON response. I do that because it makes it easier for the client code to parse and handle the response. I'll leave the NSJSONSerialization to you.