I've a problem when I try to send a POST request to my API on my server, I've followed many many different tutorials but it still doesn't work.
I know than my problem is with the POST request but I can't solve it !
So this is my code in Swift and my API in php : (and yes I've replaced the xxxx by the real IDs in my code)
To sum up server receive the request and for example if I manually enter a pseudo it works, It's really the POST method who doesn't work.. The server doesn't receive the POST parameter
Swift code :
var request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8888/academy/test.php")!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var params = ["pseudo":"test"] as Dictionary<String, String>
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(err != nil) {
println(err!.localizedDescription)
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: '\(jsonStr)'")
}
else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
var success = parseJSON["success"] as? Int
println("Succes: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: \(jsonStr)")
}
}
})
task.resume()*/
PHP Code :
$BDD_hote = 'xxxxx';
$BDD_bd = 'xxxxx';
$BDD_utilisateur = 'xxxxx';
$BDD_mot_passe = 'xxxxx';
try{
$bdd = new PDO('mysql:host='.$BDD_hote.';dbname='.$BDD_bd, $BDD_utilisateur, $BDD_mot_passe);
$bdd->exec("SET CHARACTER SET utf8");
$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}
catch(PDOException $e){
echo 'Erreur : '.$e->getMessage();
echo 'N° : '.$e->getCode();
}
$pseudo = addslashes($_POST["pseudo"]);
$req = $bdd->query("SELECT * from users WHERE pseudo='$pseudo'");
$resultArray = array();
$donnees = $req->fetch();
echo json_encode($donnees);
Thanks by advance :)
As others have pointed out, the encoding of the request is not quite right. Your server code is not expecting JSON request, but rather is using $_POST variables (which means that the request should have Content-Type of application/x-www-form-urlencoded). So that's what you should create. For example in Swift 3 and later:
var request = URLRequest(url: url)
request.httpMethod = "POST"
let parameters = ["somekey" : "valueforkey"]
request.setContent(with: parameters)
let task = session.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
// your response parsing code here
}
task.resume()
The setContent method would take a dictionary of the form ["key1": "foo", "key2" : "bar"] and populate the httpBody with something that looks like key1=foo&key2=bar. If you do that, the server will be able to parse the $_POST from the request.
extension URLRequest {
/// Set body and header for x-www-form-urlencoded request
///
/// - Parameter parameters: Simple string dictionary of parameters to be encoded in body of request
mutating func setContent(with parameters: [String: String]) {
setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let array = parameters.map { entry -> String in
let key = entry.key.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)!
let value = entry.value.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)!
return key + "=" + value
}
httpBody = array.joined(separator: "&").data(using: .utf8)!
}
}
Note, this also percent-encodes the values (and, just in case, the keys, too), which is critical. While others have advised using addingPercentEncoding with .urlQueryAllowed, sadly that will not do the job, as it will let certain reserved characters (notably +) pass unescaped. Most web services will interpret the + as a space, in conformance with the x-www-form-urlencoded spec. So, adapting an approach adopted by Alamofire, I define a character set which will encode values with the various delimiters:
extension CharacterSet {
/// Returns the character set for characters allowed in the individual parameters within a query URL component.
///
/// The query component of a URL is the component immediately following a question mark (?).
/// For example, in the URL `http://www.example.com/index.php?key1=value1#jumpLink`, the query
/// component is `key1=value1`. The individual parameters of that query would be the key `key1`
/// and its associated value `value1`.
///
/// According to RFC 3986, the set of unreserved characters includes
///
/// `ALPHA / DIGIT / "-" / "." / "_" / "~"`
///
/// In section 3.4 of the RFC, it further recommends adding `/` and `?` to the list of unescaped characters
/// for the sake of compatibility with some erroneous implementations, so this routine also allows those
/// to pass unescaped.
static var urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]#" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
var allowed = CharacterSet.urlQueryAllowed
allowed.remove(charactersIn: generalDelimitersToEncode + subDelimitersToEncode)
return allowed
}()
}
For Swift 2 rendition, see previous revision of this answer.
Try this:
let myURL = NSURL(string: "http://localhost:8888/academy/test.php")!
let request = NSMutableURLRequest(URL: myURL)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let bodyStr:String = "pseudo=test"
request.HTTPBody = bodyStr.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
// Your completion handler code here
}
task.resume()
You have to encode your data using UTF8 string encoding. If you need to set more than one field&value pairs for request body, you can change the body string, for example, "pseudo=test&language=swift". In fact, I usually create an extension for NSMutableURLRequest and add a method which takes a dictionary as parameter and sets the content of this map(dictionary) as HTTPBody using correct encoding. This may work for you:
extension NSMutableURLRequest {
func setBodyContent(contentMap: Dictionary<String, String>) {
var firstOneAdded = false
let contentKeys:Array<String> = Array(contentMap.keys)
for contentKey in contentKeys {
if(!firstOneAdded) {
contentBodyAsString += contentKey + "=" + contentMap[contentKey]!
firstOneAdded = true
}
else {
contentBodyAsString += "&" + contentKey + "=" + contentMap[contentKey]!
}
}
contentBodyAsString = contentBodyAsString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
self.HTTPBody = contentBodyAsString.dataUsingEncoding(NSUTF8StringEncoding)
}
}
And you can use this as:
request.setBodyContent(params)
I hope this helps you!
the following php code is for receiving application/url+encode encoded post message. please refer https://en.wikipedia.org/wiki/Percent-encoding
$_POST["pseudo"]
and your swift code was sending a JSON encoded string data. They are incompatible.
If you don't want to change the php code, in Swift you should send url-encode format message, li:
// UPDATED with corrections from #Rob
var params = ["param1":"value1", "papam2": "value 2"]
var body = ""
for (key, value) in params {
body = body.stringByAppendingString(key)
body = body.stringByAppendingString("=")
body = body.stringByAppendingString(value.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)
body = body.stringByAppendingString("&")
}
body = body.substringToIndex(advance(body.startIndex, countElements(body)-1)) // remove the last "&"
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
Related
I hope you all are doing well and staying safe! :)
I am new to iOS programming. I am trying to post values from a textfield to a MYSQL Database. As a first step, I tried to just print the values received on the PHP end.
The values are printed on the Swift end but on the PHP end, an empty string(null) is received. Could you please help and let me know why the string received on PHP end is null? Please help! I am stuck and unsure of what to do next.
I have tried retrieving values from the database and that code works perfectly fine.
Thanks in advance!
EDITED:
This has been now fixed. The correct code is below -
Swift Code:
struct DatatoPost : Codable{
var name : String
init() {
name = "Empty String"
}
}
var myDatatoPost = DatatoPost()
//Protocol created for this structure so that it can be applied to multiple class (View Controllers) that create a delegate for it(ManageDataDelegate)
protocol ManageDataDelegate {
func updateViewController(_ myManager : ManageData, saveOutputData: OutputData)
func didFailError(error : Error)
}
/* what action is expected to be taken on data reached through PHP file*/
struct ManageData {
var delegate : ManageDataDelegate?
var data : Data
init() {
data = Data()
}
//create POST URL based on function - this is the URL to post data to the backend.
mutating func postPHPData(){
let urlPostString = myConstant.baseURL + myConstant.postPHPValue
print(urlPostString)
performPostOperation(urlPostString)
}
//Steps to create URL and other related objects - prepare data for parsing.
mutating func performPostOperation(_ urlPostString : String) {
//1. Create URL
if let url = URL(string: urlPostString){
//Create request variable
var request : URLRequest = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
do{
let params : [String : Encodable] = ["name": myDatatoPost.name]
data = try JSONSerialization.data(withJSONObject: params, options: .init())
let body = Data(data).base64EncodedData()
print("Data is: ")
let dataString = String(data: data, encoding: .utf8)
print(dataString)
request.httpBody = body
let requestString = String(data: request.httpBody!, encoding: .utf8)
print("Request String is:")
print(requestString)
//2. Create URLSession
let session = URLSession(configuration: .default)
//3. Give the session a task
let task = session.dataTask(with: request as URLRequest, completionHandler: handlePOST(data:response:error:))
//4. Start the session
task.resume()
}catch{
print(error)
}
}
}
//Function that lists the activities that need to be completed in the URL session - GET Data.
func handlePOST(data : Data?, response : URLResponse?, error: Error?){
if error != nil {
delegate?.didFailError(error: error!)
print("error is")
print(error!)
return
}
if let safeData = data{
let dataString = String(data: safeData, encoding: .utf8)
print(dataString)
}
print(response)
}
}
PHP Code:
<?php
echo "we are here";
// Create connection
$con = mysqli_connect("localhost","username","password","dbname");
echo "we are here again";
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: ";
}
$postdata = json_decode(file_get_contents("php://input"),TRUE);
$decoded = base64_decode($postdata);
echo "decoded!";
print_r($decoded,true);
//this value is not printed
echo "postdata";
echo $postdata->name;
//this value is not printed
$name= $postdata["name"];
echo "Name";
echo $postdata["name"];
//this value is not printed
echo "Base 64";
echo base64_decode($postdata["name"]);
echo base64_decode($postdata->name);
//This value is not printed
if (empty($postdata["name"])){
echo "String is empty";
//this is printed
}
if (empty($postdata->name)){
echo "String is empty";
//This is printed
}
echo "Its done";
// Close connections
mysqli_close($con);
?>
You have specified your request’s Content-Type to be application/json. So it should be JSON, free of base64 encoding. The only time you should use base64-encoding is if you are trying to send binary data in JSON. (And even then, in that case, we would reach for application/x-www-form-urlencoded request, not application/json request.)
Anyway, to send JSON request and parse JSON response:
protocol ManageDataDelegate: class {
func didFailError(error: Error)
func didReceiveResponse(object: Any)
}
/* what action is expected to be taken on data reached through PHP file*/
struct ManageData {
weak var delegate: ManageDataDelegate? // delegates should always be weak to avoid strong reference cycle; obviously `ManageDataDelegate` must be class protocol
//create POST URL based on function - this is the URL to post data to the backend.
func postPHPData(name: String) {
let urlPostString = URL(string: MyConstant.baseURL)!.appendingPathComponent(MyConstant.postPHPValue)
print(urlPostString)
performPostOperation(urlPostString, name: name)
}
//Steps to create URL and other related objects - prepare data for parsing.
func performPostOperation(_ url: URL, name: String) {
//Create request variable
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
do {
let params = ["name": name]
let body = try JSONSerialization.data(withJSONObject: params)
// 1. for diagnostic purposes, let's look at the JSON
if let json = String(data: body, encoding: .utf8) {
print("JSON is:", json)
}
request.httpBody = body
//2. Create URLSession
let session = URLSession(configuration: .default)
//3. Give the session a task
let task = session.dataTask(with: request, completionHandler: handlePOST(data:response:error:))
//4. Start the session
task.resume()
//5. If creating a URLSession locally, make sure to invalidate it when the request is done or else you will leak memory; better, create one `URLSession` and reuse it for all of your requests (and then you don't need/want to invalidate it)
session.finishTasksAndInvalidate()
} catch {
print(error)
}
}
enum ManageDataError: Error {
case unknownError(Data?, URLResponse?, Error?)
case notJsonResponse(String)
}
//Function that lists the activities that need to be completed in the URL session - GET Data.
func handlePOST(data: Data?, response: URLResponse?, error: Error?) {
guard let responseData = data, error == nil else {
let error = error ?? ManageDataError.unknownError(data, response, error)
delegate?.didFailError(error: error)
print("error is")
print(error)
return
}
if let object = try? JSONSerialization.jsonObject(with: responseData) {
delegate?.didReceiveResponse(object: object)
} else if let string = String(data: responseData, encoding: .utf8) {
delegate?.didFailError(error: ManageDataError.notJsonResponse(string))
} else {
delegate?.didFailError(error: ManageDataError.unknownError(data, response, error))
}
print(response ?? "No response")
}
}
There are a variety of refinements buried in the above (if creating a session, you must invalidate it when finished; passing responses to the delegate; making sure delegate reference is weak to avoid strong reference cycles; etc.), but hopefully this illustrates the idea: No base64-encoding is needed or desired with JSON requests.
Note, you have specified the request’s Accept to also be application/json so I would make sure it did precisely that:
<?php
header("Content-Type: application/json");
// Create connection
$con = mysqli_connect("localhost","username","password","dbname");
// Check connection
if (mysqli_connect_errno())
{
$result = [
"success" => false,
"message" => "Failed to connect to MySQL: " . mysqli_connect_error()
];
echo json_encode($result, JSON_PRETTY_PRINT);
exit();
}
$postdata = json_decode(file_get_contents("php://input"), true);
if (isset($postdata["name"]))
{
$result = [
"success" => true,
"name" => $postdata["name"]
];
}
else
{
$result = [
"success" => false,
"message" => "'name' not found",
"postdata" => $postdata
];
}
echo json_encode($result, JSON_PRETTY_PRINT);
// Close connections
mysqli_close($con);
?>
So, this parses the JSON and checks for name, but returning a JSON response, which is what the client was looking for.
There are other refinements I would suggest (e.g. I would use JSONEncoder and JSONDecoder rather than JSONSerialization; not create new URLSession for every request; usually a “network controller” like this would be a reference type so that you can use the same one wherever needed; I would use a framework such as Laravel in the server code, etc.), but I did not want to stray too far from the question at hand.
How can I pass an array to my Php backend using swift. Do i have to for loop each value and append it to the request body?
Here is my code
let url = URL(string: "url.com/page")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let id = user?["id"] as! String
let party = partyName.text!
let body = "id=\(id)&party_name=\(party)&party_invited=\(usersInvited)"
//********--usersInvited-- is the array i want to pass
request.httpBody = body.data(using: String.Encoding.utf8)
URLSession.shared.dataTask(with: request, completionHandler: { (data:Data?, response:URLResponse?, error:Error?) in
DispatchQueue.main.async(execute: {
if error == nil{
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
guard let parseJSON = json else{
print("Error while parsing")
return
}
print(parseJSON["status"])
} catch{
print("Caught an error: \(error)")
}
} else{
print("Error: \(error)")
}
})
}).resume()
But that code sends the array as one whole string with an output like this: ["57", "60"]
I'm guessing, but it looks like you want to JSON encode your array, but as a URL parameter?
(I've assumed that usersInvited is an array of strings)
You could go via JSONSerialisation?
let data = try! JSONSerialization.data(withJSONObject: usersInvited, options: [])
let string = String(data: d, encoding: .utf8)!
let body = "id=\(id)&party_name=\(party)&party_invited=\(string)"
Or if that's not quite what you want (you've got a space after the comma in your question), you could just do it by hand?
let string = "[" + usersInvited.map { "\"\($0)\"" }.joined(separator: ", ") + "]"
My vote would be to use option 1 and make your server accept what it outputs.
If you mean you want it to look like party_invited=1,2,3,4 then you could use joined to convert the array like this
let string = usersInvited.joined(separator: ",")
let body = "id=\(id)&party_name=\(party)&party_invited=\(string)"
If you mean you want this party_invited=1&party_invited=2&party_invited=3 then you can use map and joined
let string = usersInvited.map { "party_invited=\($0)" }.joined(separator: "&")
let body = "id=\(id)&party_name=\(party)&\(string)"
I declared a function to send information from some textfields (POST), then I get a response with the information given. I also used components(separatedBy: String) to get an array with the information from every field. What am trying to do now is to use this information (one from the array) to store/use it so I can show the user, in a new view, the information saved.
My Swift looks like the following
#IBAction func enviarInfo(_ sender: Any) {
let request = NSMutableURLRequest(url: NSURL(string: "http://www.mydomain/index.php")! as URL)
request.httpMethod = "POST"
//The String with the vars that will be sent to the $_POST["var"]
let postString = "nombre=\(nombreText.text!)&aPaterno=\(apaternoText.text!)&aMaterno=\(amaternoText.text!)&genero=\(genero.text! &email=\(emailText.text!)&telefono=\(telefonoText.text!)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(String(describing: error))")
return
}
print("response = \(String(describing: response))")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(String(describing: responseString))")
//Use a split method to get relevant information only
let string: String = responseString! as String
var str = string.components(separatedBy: "##")
let resultadoUno = str[1]
var str2 = resultadoUno.components(separatedBy: ">>")
let resultadoDos = str2[0]
var str3 = resultadoDos.components(separatedBy: ";")
}
task.resume()
}
If I print, for example, str3[5] I get the phone number, or a name with str3[0], but what I don't know is, how to save the data and show it to the user via labels (label.text = the value from the array).
You can easily save Response string to UserDefaults, and restore and use them later.
First, define a class level constant as UserDefaults key:
let key = "responseString"
Second, save the string:
UserDefaults.standard.set(responseString, forKey: key)
UserDefaults.standard.synchronize()
Restore and use it when you need it:
guard let repsonseString = UserDefaults.standard.object(forKey: key) as? String else {
return
}
var strArray = repsonseString.components(separatedBy: "##")
if strArray.count > 0 {
let str2 = strArray[0].components(separatedBy: ">>")
// do something with str2
}
if strArray.count > 1 {
let str3 = strArray[1].components(separatedBy: ";")
if str3.count > 5 {
self.phoneLabel.text = str3[5]
}
}
The better practice is the PHP returns the dictionary instead of array, like:
{
phoneNumber:123456789,
userName:"Joy"
}
You get the response on iOS and convert JSON dictionary to Swift dictionary, and parse it into a Model(Like a User class). Then it will be very convenient to access data like: self.phoneNumberLabel.text = user.phoneNumber
I am trying to send a POST request to a web server, however the value I am trying to send is in a variable named temperatureValue. The web server looks for the POST variable "temperature". This is how I am declaring my postData. How do I pass in this variable?
let postData = NSMutableData(data: "temperature=temperatureValue".dataUsingEncoding(NSUTF8StringEncoding)!)
The rest of the code for the POST is included below, but my main question is how to format the above to allow my variable temperatureValue to be saved into postData.
//Assign the url post address, post the data to the php page
let request = NSMutableURLRequest(URL: NSURL(string: "http://pi.access.com/stateBlinds.php")!,
cachePolicy: .UseProtocolCachePolicy,
timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.HTTPBody = postData
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? NSHTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
You can use string interpolation:
let temperatureValue = 10.5
request.HTTPBody = "temperature=\(temperatureValue)".dataUsingEncoding(NSUTF8StringEncoding)
If temperatureValue is an optional, though, you have to unwrap it.
let temperatureValue: Double? = 10.5
let postString: String
if let value = temperatureValue {
postString = "temperature=\(value)"
} else {
postString = "temperature="
}
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
Also note that this very simple example works only if dealing with very simple "values" (e.g. just alphanumeric with no spaces or special characters). If you take this pattern and try it with general strings, you have to percent-escape the value. But for simple numeric values, the above will suffice.
The purpose of this code is to send data to a SQL database using PHP script.
But when I try to run it I get the following error:
Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
This is my code:
// Send userdata to server side
let myURL = NSURL(string: "http://localhost/userRegister.php");
let request = NSMutableURLRequest(URL:myURL!);
request.HTTPMethod = "POST";
let postString = "email=\(userEmail)&password=\(userPassword)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
// Create the task and execute it
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data,response, error in
if error != nil{
print("error=\(error)")
return
}
var err: NSError?
do
{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = json {
var resultValue = parseJSON["status"] as? String
print("result: \(resultValue)")
var isUserRegisterd:Bool = false;
if(resultValue=="Success")
{
isUserRegisterd = true
}
var messageToDisplay: String = (parseJSON["message"] as? String)!
if(!isUserRegisterd)
{
messageToDisplay = (parseJSON["message"] as? String)!
}
dispatch_async(dispatch_get_main_queue(), {
var myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert);
let okAction = UIAlertAction(title: "Oké", style: UIAlertActionStyle.Default){
action in
self.dismissViewControllerAnimated(true, completion: nil);
}
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil);
});
}
}
catch
{
print(error)
}
}
task.resume()
What is the problem here?
That error generally means that the NSData doesn't contain valid JSON.
You should look at the response and the string representation of the data because if the server encountered a problem, it most likely would have returned a statusCode in the NSHTTPURLResponse (where 200 means that everything was OK, RFC 2616 describes what the other error codes mean) and the NSData likely contains HTML or text describing the nature of the problem:
do {
// your code where you `try` parsing the JSON response goes here
} catch {
print(error)
if data != nil {
let string = String(data: data!, encoding: NSUTF8StringEncoding)
print(string)
}
print(response)
}
When you look at the NSURLResponse and NSData objects, you will you be far more likely to diagnose the problem.
--
By the way, I might advise specifying the Content-Type of the request. Also, I'd suggest percent-escaping the email address and password. The latter is important because if the values contain special characters (e.g. + and & are notable problems), the data will not be processed correctly by the server.
let url = NSURL(string: "http://localhost/userRegister.php")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let encodedEmail = userEmail.stringByAddingPercentEncodingForFormUrlencoded()
let encodedPassword = userPassword.stringByAddingPercentEncodingForFormUrlencoded()
let postString = "email=\(encodedEmail)&password=\(encodedPassword)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
Where
extension String {
/// Percent escape value to be added to a HTTP request
///
/// This percent-escapes all characters besize the alphanumeric character set and "-", ".", "_", and "*".
/// This will also replace spaces with the "+" character as outlined in the application/x-www-form-urlencoded spec:
///
/// http://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm
///
/// - returns: Return percent escaped string.
func stringByAddingPercentEncodingForFormUrlencoded() -> String? {
let allowedCharacters = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._* ")
return stringByAddingPercentEncodingWithAllowedCharacters(allowedCharacters)?.stringByReplacingOccurrencesOfString(" ", withString: "+")
}
}
Alternatively, you can build the character set of allowed characters by starting with URLQueryAllowedCharacterSet, but you still have to remove a few characters as it will otherwise that allows certain characters pass unescaped (e.g. +). See https://stackoverflow.com/a/35912606/1271826.
Or you could use a framework like Alamofire which takes care of these details for you.
In my case, even the following code was causing this error by appending extra // slashes at the beginning of the output.
$arr = array("status" => 1, "msg" => "Your message goes here!");
echo json_encode($arr);
The reason was that these extra characters were being printed in other file that I included to this file.