Swift 2.1 POST through HTTPBody not working - php

I am trying to send data via POST to a server in Swift 2.1, however, the server never appears to receive any of the data.
Swift:
let url = NSURL(string: "http://www.myserver.com/test.php");
let request = NSMutableURLRequest(URL:url!)
request.HTTPMethod = "POST";
let postString = "firstName=TestName1&lastName=TestName2";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let session = NSURLSession.sharedSession();
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
let urlContent = NSString(data: data!, encoding: NSUTF8StringEncoding) as NSString!
print("Data: \(urlContent)");
});
task.resume();
PHP:
<?php
// Read request parameters
$firstName= $_REQUEST["firstName"];
$lastName = $_REQUEST["lastName"];// Store values in an array
$returnValue = array(“firstName”=>$firstName, “lastName”=>$lastName);
// Send back request in JSON format
echo json_encode($returnValue); ?>
Returns:
Data: {"firstName":null,"lastName":null}
I have canvased the web in an attempt to solve this problem, however, most of the solutions are out of date as they do not conform to the deprecations and changes brought with Swift 2.
Any ideas?

By removing the following lines of code, I got the data to return correctly:
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")

Related

URLSession not sending data to PHP API

I am using this code below to send a HTTP request to my PHP API
static func submitNumber(parameters: [String: Any]){
print("parameters", parameters)
guard let url = URL(string: Constants.phoneVerifyUrl) else {
print("URL not found")
return
}
let datas = try! JSONSerialization.data(withJSONObject: parameters, options: [])
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = datas
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let urlSession = URLSession.shared.dataTask(with: request) { data, _, error in
if error != nil {
print("error", error?.localizedDescription ?? "")
return
}
do {
if let data = data {
print("data", data)
let decodedData = try JSONDecoder().decode(DataModels.self, from: data)
DispatchQueue.main.async {
let noError = decodedData.noError
let dataStr = decodedData.dataStr
print("noError", noError)
print("dataStr", dataStr)
}
} else {
print("No Data received")
}
} catch let JsonError {
print("JSON error", JsonError.localizedDescription)
}
}
urlSession.resume()
}
And then in my PHP API, I try to receive the data like this
<?php
if(isset($_POST)){
$phoneNumber = $_POST['phoneNumber'];
//Run Code here
}
?>
When I do
print("parameters", parameters)
This is what I get (As expected)
parameters ["phoneNumber": "1234567890"]
But then, for a reason I don't know, the code in my PHP API is not executing. The PHP code is perfectly working because I use the same API for my Android app and it works fine, so I know the issue is not from my PHP API
And when I also do this print("data", data) I get a random number like this data 8402 bytes
For me, I believe I'm not passing the parameters in the right way to my API, Since I'm new to Swift, I don't know how it's done
And for my URL string Constants.phoneVerifyUrl, it's okay
Please note: I don't want to temper with my PHP API as I also use it for my Android app. So I need only to fix my Swift code
I found an answer from to create post body request data using below code.
var jsonData:Data?
do {
jsonData = try JSONSerialization.data(withJSONObject: dic, options: .prettyPrinted)
} catch {
print(error.localizedDescription)
}
and then create the request like this.
let url = URL(string: "https://blah.com/server/dudes/decide/this")!
var request = URLRequest(url: url)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
request.httpBody = jsonData
Okay... My first answer was wrong, but I've got it figured out.
First I removed this lines
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
And replaced it with this
request.addValue("application/json", forHTTPHeaderField: "Accept")
Then I changed my Data parameters dictionary from JSON to String
var datas = parameters.toQueryString.data(using: .utf8)!
Below is the Dictionary extension of toQueryString
extension Dictionary {
var toQueryString: String? {
return self.reduce("") { "\($0!)\($1.0)=\($1.1)&" }
}
}

swift PUT API from json object

I am trying to make an api call I build the json object. But the data is not being passed I believe it is the formatting of the data when passed the service only has examples in php which i have posted below
API Docs: http://middleware.idxbroker.com/docs/api/methods/index.html#api-Leads-putLead
php call
// PUT lead in to IDX Broker
$url = 'https://api.idxbroker.com/leads/lead';
$data = array(
'firstName'=>$firstname,
'lastName'=>$lastname,
'email'=>$email
);
$data = http_build_query($data); // encode and & delineate
$method = 'PUT';
Swift Code to build json object
/// Create lead from text fields
let jsonObject: [String: String] = [
"firstName": (firstName.text! as String),
"lastNmae": lastName.text!,
"email": Email.text!,
"phoneNumber": phoneNumber.text!,
"city": (city.text as AnyObject) as! String,
"recieveUpdates": (switchIsChanged(recieveUpdates: recieveUpdates) as AnyObject) as! String
]
The API Call
class func putLead(lead: AnyObject){
let urlString = "https://api.idxbroker.com/leads/lead"
let url = NSURL(string: urlString)
print(lead)
var downloadTask = URLRequest(url: (url as URL?)!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 20)
/******************** Add Headers required for API CALL *************************************/
downloadTask.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
downloadTask.setValue(APICalls.getAccessKey(), forHTTPHeaderField: "accesskey")
downloadTask.setValue("json", forHTTPHeaderField: "outputtype")
downloadTask.httpMethod = "PUT"
downloadTask.httpBody = (lead as? Data)
/******************** End Headers required for API CALL *************************************/
URLSession.shared.dataTask(with: downloadTask, completionHandler: {(data, response, error) -> Void in
/// Status Returned from API CALL
if let httpResponse = response as? HTTPURLResponse {
print("statusCode: \(httpResponse.statusCode)")
}
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(jsonData ?? "No Return")
}).resume()
/******** End URL Session **********/
}
Working Version
let newLead = "firstName=\(firstName.text!)&lastName=\(lastName.text!)&email=\(Email.text!)&phoneNumber=\(phoneNumber.text!)&city=\(String(describing: city.text))&recieveUpdates=\((switchIsChanged(recieveUpdates: recieveUpdates) as AnyObject) as! String)"
let newData = newLead.data(using: String.Encoding.utf8)
/// API Call with passing json String
APICalls.putLead(lead: newData!)
I was able to get it working by making the following changes to your putLead() function:
class func putLead(lead: [String:String]){
let urlString = "https://api.idxbroker.com/leads/lead"
let url = NSURL(string: urlString)
var httpBodyString = ""
for (key,value) in lead{
let currentKey = key.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
let currentValue = value.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
httpBodyString += "\(currentKey!)=\(currentValue!)&"
}
var downloadTask = URLRequest(url: (url as URL?)!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 20)
/******************** Add Headers required for API CALL *************************************/
downloadTask.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
downloadTask.setValue(<API_KEY_HERE>, forHTTPHeaderField: "accesskey")
downloadTask.httpMethod = "PUT"
downloadTask.httpBody = httpBodyString.data(using: String.Encoding.utf8)
/******************** End Headers required for API CALL *************************************/
URLSession.shared.dataTask(with: downloadTask, completionHandler: {(data, response, error) -> Void in
/// Status Returned from API CALL
if let httpResponse = response as? HTTPURLResponse {
print("statusCode: \(httpResponse.statusCode)")
}
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(jsonData ?? "No Return")
}).resume()
/******** End URL Session **********/
}

Nothing is getting posted to my php script

I have a php script on my server and I am trying to post data from my ios app, but when I print the post variables I get a nil. Any idea why that is?
Swift
let url: NSURL = NSURL(string: "https://xxxxxx.com/myFile.php")!
let request:NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
let bodyData = "username=\(username.text)&password=\(password.text)"
request.httpMethod = "POST"
request.httpBody = bodyData.data(using: String.Encoding.utf8);
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
NSURLConnection.sendAsynchronousRequest(request as URLRequest, queue: OperationQueue.main)
{
(response, data, error) in
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
//
print("response \(responseString)")
}
PHP
print_r($_POST); //prints: ([username] => xxxxxx [password] => yyyyyy)
json_encode($postVarUser);
json_encode($postVarPass);
May be it is the problem of echo($postUser);
just use json_encode($postUser);

Swift Xcode 6.1.1 POST Request not posting

I simply want to POST some data from Swift to a PHP script. I've Googled for about two days on this and everyone seems to be doing the same thing, but it's not working for me. I have this Swift code triggered on viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
let request = NSMutableURLRequest(URL: NSURL(string: "http://mywebsite.com/scriptToHandlePOST.php")!) // it forces me to add the !
request.HTTPMethod = "POST"
var err: NSError?
let postString = "var1=value1&var2=value2".dataUsingEncoding(NSUTF8StringEncoding)
var postLength:NSString = String( postString!.length )
request.HTTPBody = postString
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error -> Void in
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println(response) // this returns a 200
println(strData!) // this returns an empty array of the $_POST variable
}
task.resume() // this is needed to start the task
}
My PHP script is simply just trying to get $_POST data:
<?php
print_r($_POST);
?>
Since the $_POST returns an empty array I suspect the POST request is never making it to my website. Do you see anything wrong in the code?

json swift ios - sending parameters to a php-sql

Hello I am trying to send a couple of parameters from an SWIFT IOS application to a PHP-SQL database using JSON. Has tried several examples both sycronus and asyncronus but I do not get it to work.
Keep troubling with the converting of the JSON parameter string to a format that will be received on the other side.. (when i try in the browser it will work..but not from the app itself)
Here is the code - from PLAYGROUND
(The response is API Response: OPTIONAL (Missing JSON)
// Playground - noun: a place where people can play
import UIKit
import CoreLocation
var str = "Hello, playground debug use of JSON and PHP"
import Foundation
let url = NSURL(string:"http://mywebserver-replaced.no/POSITION/update.php?")
let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
var request = NSMutableURLRequest(URL: url!, cachePolicy: cachePolicy, timeoutInterval: 2.0)
request.HTTPMethod = "POST"
// set Content-Type in HTTP header
let boundaryConstant = "----------V2ymHFg03esomerandomstuffhbqgZCaKO6jy";
let contentType = "multipart/form-data; boundary=" + boundaryConstant
NSURLProtocol.setProperty(contentType, forKey: "Content-Type", inRequest: request)
// set data
var dataString = " "
dataString = "json={\"FBID\":10,\"Driving\":1,\"Latitude\":\"68.123\",\"Longitude\":\"22.124\",\"Time\":\"18:24\",\"Date\":\"07.10.2014\",\"Heading\":90}"
let requestBodyData = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
request.HTTPBody = requestBodyData
println("\(requestBodyData)") // This will print "Optional(<6a736f6e...and so on..
// And except the optional it is quite correct.. json={
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
// set content length
// NSURLProtocol.setProperty(requestBodyData.length, forKey: "Content-Length", inRequest: request)
var response: NSURLResponse? = nil
var error: NSError? = nil
let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)
let results = NSString(data:reply!, encoding:NSUTF8StringEncoding)
println("API Response: \(results)")
What am i dooing wrong?
You are setting wrong Content-Type
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
should be
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
And also
dataString = "json={\"FBID\":10,\"Driving\":1,\"Latitude\":\"68.123\",\"Longitude\":\"22.124\",\"Time\":\"18:24\",\"Date\":\"07.10.2014\",\"Heading\":90}"
Remove the json=, which makes the body not a valid json.

Categories