guys, i am having problem of posting json data through alamofire 4 with swift3 and also the problem of retrieving the json data at XAMPP server side using php.
My swift 3 code did trigger the php script at XAMPP, but somehow i can't get it through $_POST variable in php
Here is my code,
func uploadImage(image: UIImage){
//Now use image to create into NSData format
let imageData:NSData = UIImagePNGRepresentation(image)! as NSData
//convert the nsdata to base64 encoded string
let strBase64:String = imageData.base64EncodedString(options: .lineLength64Characters)
// let parameters = ["image": strBase64] as Dictionary
let parameters = ["image": strBase64]
print(strBase64)
Alamofire.request("http://localhost/Test/api/UploadPhoto.php",method: .post, parameters: parameters, encoding: JSONEncoding.default).response { response in
print(response)
}
}
Here is my server side code(the script did get triggered by the call from alamofire, but somehow i just can't get the data through calling$_POST["image"])
<?php
//scripts below did get triggered, but can't get the json data through calling $_POST["image"];
$imageString = $_POST["image"];
$filename_path = md5(time().uniqid()).".png";
$data = base64_decode($imageString);
file_put_contents('../AllImages/'.$filename_path, $data);
echo json_encode($_POST["image"]);
?>
if possible, please help me, i have been struggled for nearly a week, but can't find many clues
Thank you
i have found a way to solve this problem, basically, i used urlsession.shared.datatask to help me instead of alamofire with the post request,
here is my ios side code
func uploadImage(image: UIImage, completionHandler: #escaping (String) ->()){
// Now use image to create into NSData format
let imageData:NSData = UIImagePNGRepresentation(image)! as NSData
//convert the nsdata to base64 encoded string
let strBase64:String = imageData.base64EncodedString(options: .lineLength64Characters)
// prepare json data
let json: [String: Any] = ["image": strBase64]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "http://10.10.10.72/Test/api/UploadPhoto.php")!
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
do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject] else {
throw JSONError.ConversionFailed
}
completionHandler(json["sign"] as! String)
} catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}
task.resume()
}
i used dictionary to store my data, and converted it to json data format to be sent to server
let json: [String: Any] = ["image": strBase64]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
Then at the php side, i retrieved it by using
$entityBody = file_get_contents('php://input');
, then i decoded from json which produced me an array and i can access my value by referencing image, so full php side of code as below:
<?php
//get the posted json data
$entityBody = file_get_contents('php://input');
//decode the json data
$decoded = json_decode($entityBody, TRUE);
$imageString = $decoded["image"];
//create a unique name for the image
$filename_path = md5(time().uniqid()).".png";
//converted the image string back to image
$data = base64_decode($imageString);
//put it on the desired location
file_put_contents('../AllImages/uploads/signature/'.$filename_path, $data);
$response = array();
//create the response
$response['sign'] = '../AllImages/uploads/signature/'.$filename_path;
echo json_encode($response);
?>
do note here, i encode the json data again to be sent back as a response from php to my ios side, and you need to decode the response from json, so the full idea is if you encode the value to json from one side, you need to decode it from another side to access the value properly, correct me if i am wrong, i am glad that my app is up and running now with all the requests now :D
Related
I'm developing an app in Swift 3 where I need to pass an integer value from the app to an online SQL server.
My Swift code is as following:
func saveData(data: Int) {
// prepare json data
let json: [String: Any] = ["matchScore": ["\(data)"]]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "http://mywebpage.com/swift/addToSQL.php")!
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
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(responseJSON)
}
}
task.resume()
}
And the part of the PHP file where I'm supposed to get the JSON data:
$jsonData = file_get_contents("php://input");
$json = json_decode($jsonData, true);
$matchScore = $json['matchScore'][1];
However, the database is not getting anything. I found out that if I set $matchScore = 42 (example) it works and posts to SQL database, so it has to be the parsing that's the issue.
What am I missing out here?
Thanks.
I am having trouble using URLSession to access JSON data generated by a PHP file.
I am both confused about the Swift 3 syntax and the completion handlers.
So far I have:
override func viewDidLoad() {
super.viewDidLoad()
var data : NSMutableData = NSMutableData()
let urlString: String = "http://seemeclothing.xyz/service.php"
let urlObject: URL = URL(string: urlString)!
let response = URLResponse
let config = URLSessionConfiguration.default
let sessionObject: URLSession
sessionObject.dataTask(with: urlObject) { (Data?, URLResponse?, Error?) in
print(data)
print(URLResponse)
print(Error)
}
sessionObject.resume()
}
I want sessionObject to go to my server and print JSON data from PHP file.
Any help would be greatly appreciated.
I would strongly suggest using Alamofire. It abstracts away all the tedious stuff in URLSession. I switched to this a few days ago and am a happy camper since then.
For your problem:
Alamofire.request("https://httpbin.org/get").responseJSON { response in
print(response.request) // original URL request
print(response.response) // HTTP URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
I have been struggling to get a web service to work with a native Swift application when a user is attempting to upload data using the "&" character, amongst others.
After various attempts at escaping the request, I am at a loss and looking for some advice to solving this. I have included a some code from both the Swift application and the PHP scripts for reference. The data is able to be posted to the server (I am using FileMaker Server PHP API), but not when the "&" is included in a user-submitted value as the JSON is being cut short when PHP hits that character.
The postData argument in the Swift request sample is a dictionary in JSON format, which is encoded using the below code from JSONStringify:
func JSONStringify(value: AnyObject, prettyPrinted: Bool = false) -> String {
let options = NSJSONWritingOptions.PrettyPrinted
if NSJSONSerialization.isValidJSONObject(value) {
do {
let data = try NSJSONSerialization.dataWithJSONObject(value, options: options)
if let string = NSString(data: data, encoding: NSUTF8StringEncoding) {
return string as String
}
} catch {
return ""
}
}
return ""
}
Swift Request
class func returnAnyObject (phpFile:String, postData:String) -> AnyObject? {
let server:String = "http://myserver.com"
let url = NSURL(string: "\(server)\(phpFile)")
let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
let request = NSMutableURLRequest(URL: url!, cachePolicy: cachePolicy, timeoutInterval: 10.0)
request.HTTPMethod = "POST"
// set data
let dataString = postData.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let requestBodyData = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
request.HTTPBody = requestBodyData
var response: NSURLResponse? = nil
do {
let reply: NSData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
if let results = NSString(data:reply, encoding:NSUTF8StringEncoding) {
return results
} else {
return nil
}
} catch {
return nil
}
}
PHP
Below is the relevant portion of the PHP script. Perhaps there is some step I am missing with this as well?
<?php
error_reporting(E_ERROR | E_WARNING | E_PARSE);
$req1 = '../../FileMaker.php';
$req2 = '../../FM_Connect.php';
require_once $req1;
require_once $req2;
//set fixed variables
$layout = 'php_Lineitems';
//Define passed variables
$json = $_POST['json'];
$json = stripslashes($json);
$fieldArray = json_decode($json); // This is now an associative array
?>
Don't put the JSON as a string, you don't need to stringify it, should be of NSData type.
Then you set that in the body of your request directly.
Note on the PHP side you won't be able to access $_POST['json'].
You will need to change your code to:
$json = json_decode(file_get_contents('php://input'));
Is the below code a properly formatted POST request? It seems as those the entire contents are being passed via the URI and not via POST. I only have a very primitive understanding of PHP and URL requests in general so the server-side code has been included below as well.
I noticed this was an issue while attempting to upload base64 encoded images (as demonstrated below) to the server. Upon submitting the request, the server would return an error stating the that URI exceeds the maximum length, which leads me to believe that this isn't a proper approach to submitting a POST request. The entire process works if the image is only 10x10px, but that isn't going to do the trick and the main priority here is understanding the correct approach.
What is the proper approach to submitting a POST request, similar to the below example?
How can the POST data be received by the server and will the JSON need slashed stripped if it is properly submitted via POST?
Swift
if let imageData = UIImagePNGRepresentation(self.image!) {
let encodedImage = imageData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
let dict = ["barcode":self.barcode, "imageData":encodedImage]
let json = JSONStringify(dict, prettyPrinted: false)
let jsonEncoded = CFURLCreateStringByAddingPercentEscapes(
nil, json, nil, "!*'();:#&=+$,/?%#[]", CFStringBuiltInEncodings.UTF8.rawValue)
let server:String = GlobalVars.serverAddress
let phpFile:String = "/php/Inventory/UpdateItemImage.php"
let baseURL = NSURL(string: "\(server)\(phpFile)")
let url = NSURL(string: "?json=\(jsonEncoded)", relativeToURL: baseURL)
let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
let request = NSMutableURLRequest(URL: url!, cachePolicy: cachePolicy, timeoutInterval: 10.0)
request.HTTPMethod = "POST"
let dataString = ""
let requestBodyData = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
request.HTTPBody = requestBodyData
var response: NSURLResponse? = nil
do {
let reply = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
return true
} catch {
return false
}
}
PHP
<?php
// Setup DB connection etc..
//..
//Define passed variables
$json = $_GET['json'];
$json = stripslashes($json);
$fieldArray = json_decode($json);
$barcode = $fieldArray->{"barcode"};
$imageData = $fieldArray->{"imageData"};
// etc....
?>
This question already has answers here:
How to make HTTP request in Swift?
(21 answers)
Closed 8 years ago.
I want a variable in php to get over in swift (or get the value for the variable). How can I do that?
$name = "William";
How can I get this string "William" to my Swift script? Can anyone help me?
I know it's something with JSON and POST or something but otherwise I am complete lost.
When you want to get data from PHP to an iOS device, I would recommend having the PHP code send it as JSON. JSON is easier for the the client app to parse (especially as your web service responses get more complicated) and it makes it easier to differentiate between a valid response and some generic server error).
To send JSON from PHP, I generally create an "associative array" (e.g., the $results variable below), and then call json_encode:
<?php
$name = "William";
$results = Array("name" => $name);
header("Content-Type: application/json");
echo json_encode($results);
?>
This (a) specifies a Content-Type header that specifies that the response is going to be application/json; and (b) then encodes $results.
The JSON delivered to the device will look like:
{"name":"William"}
Then you can write Swift code to call NSJSONSerialization to parse that response. For example, in Swift 3:
let url = URL(string: "http://example.com/test.php")!
let request = URLRequest(url: url)
// modify the request as necessary, if necessary
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("request failed \(error)")
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: String], let name = json["name"] {
print("name = \(name)") // if everything is good, you'll see "William"
}
} catch let parseError {
print("parsing error: \(parseError)")
let responseString = String(data: data, encoding: .utf8)
print("raw response: \(responseString)")
}
}
task.resume()
Or in Swift 2:
let url = NSURL(string: "http://example.com/test.php")!
let request = NSMutableURLRequest(URL: url)
// modify the request as necessary, if necessary
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard let data = data else {
print("request failed \(error)")
return
}
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: String], let name = json["name"] {
print("name = \(name)") // if everything is good, you'll see "William"
}
} catch let parseError {
print("parsing error: \(parseError)")
let responseString = String(data: data, encoding: NSUTF8StringEncoding)
print("raw response: \(responseString)")
}
}
task.resume()
I'm answering this as an iOS/PHP dev rather than a Swift programmer.
You need to send an HTTP request to the webserver hosting the PHP script, which will return the contents of the web page given any specified parameters.
For example, if you sent an GET HTTP request to the following PHP script, the response would be "William" in the form of NSData or NSString depending on the method you use.
<?php
$name = "William";
echo $name;
?>
With a parameter GET http://myserver.com/some_script.php?name=William:
<?php
$name = $_GET['name']; // takes the ?name=William parameter from the URL
echo $name; // William
?>
As to the Swift side of things, there is a perfectly valid answer here which denotes one of the myriad methods of sending a request: https://stackoverflow.com/a/24016254/556479.