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?
Related
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)&" }
}
}
I'm working on an app in Swift. I need to call PHP webservice from this app.
Below code for webservice:
// ViewController.swift
// SwiftPHPMySQL
//
// Created by Belal Khan on 12/08/16.
// Copyright © 2016 Belal Khan. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
//URL to our web service
let URL_SAVE_TEAM = "http://192.168.1.103/MyWebService/api/createteam.php"
//TextFields declarations
#IBOutlet weak var textFieldName: UITextField!
#IBOutlet weak var textFieldMember: UITextField!
//Button action method
#IBAction func buttonSave(sender: UIButton) {
//created NSURL
let requestURL = NSURL(string: URL_SAVE_TEAM)
//creating NSMutableURLRequest
let request = NSMutableURLRequest(URL: requestURL!)
//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.dataUsingEncoding(NSUTF8StringEncoding)
//creating a task to send the post request
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if error != nil{
print("error is \(error)")
return;
}
//parsing the response
do {
//converting resonse to NSDictionary
let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
//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()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I have this array:
let arr = ["aaa", "wassd", "wesdsd"]
Now I need to send this array as parameter like this:
let postParameters = "name="+teamName!+"&member="+memberCount!;
I've done this:
let postParameters = "name="+teamName!+"&member="+memberCount!+"&arr="+arr;
but getting this error:
Expression was too long to be solved in a reasonable time. consider breaking the expression into distinct sub expressions.
Any help would be appreciated.
A little confused about what you are trying to achieve exactly, but it seems you are trying to send an array in a form-url-encoded request which is not how it works.
You can either iterate through the array and individually assign them to values in the request parameter with something like so:
var postParameters = "name=\(teamName)&member=\(member)"
let arr = ["aaa", "wassd", "wesdsd"]
var index = 0
for param in arr{
postParameters += "&arr\(index)=\(item)"
index++
}
print(postParameters) //Results all array items as parameters seperately
Ofcourse, this is a kind of dirty solution and is assuming I'm correct about you trying to send an array incorrectly. If possible, I would send the request as an application/json request, as this would make things much easier and less dirty:
func sendRequest() {
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
/* Create session, and optionally set a NSURLSessionDelegate. */
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
guard var URL = NSURL(string: "http://192.168.1.103/MyWebService/api/createteam.php") else {return}
let request = NSMutableURLRequest(URL: URL)
request.HTTPMethod = "POST"
// Headers
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
// JSON Body
let bodyObject = [
"name": "\(teamName)",
"member": "\(member)",
"arr": [
"aaa",
"wassd",
"wesdsd"
]
]
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(bodyObject, options: [])
/* Start a new Task */
let task = session.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if (error == nil) {
// Success
let statusCode = (response as! NSHTTPURLResponse).statusCode
print("URL Session Task Succeeded: HTTP \(statusCode)")
}
else {
// Failure
print("URL Session Task Failed: %#", error!.localizedDescription);
}
})
task.resume()
session.finishTasksAndInvalidate()
}
Hopefully this can get you in the right direction. Good luck!
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")
Hi I am trying to connect my iOS app to my PHP API.
I am sending JSON POST to my PHP API but I am getting an empty array as Output.
My Swift Code
#IBAction func JSONButtonAction(sender: AnyObject) {
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
var session = NSURLSession(configuration: configuration)
var usr = "dsdd"
var pwdCode = "dsds"
var image : UIImage = clickedPhotoView.image!
var imageData = UIImagePNGRepresentation(image)
let base64String = imageData.base64EncodedStringWithOptions(.allZeros)
let params:[String: AnyObject] = [
"email" : usr,
"image" : base64String ]
let url = NSURL(string:"http://localhost/app/")
let request = NSMutableURLRequest(URL: url!)
let boundaryConstant = "Boundary-7MA4YWxkTLLu0UIW"; // This should be auto-generated.
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.allZeros, error: &err)
let task = session.dataTaskWithRequest(request) {
data, response, error in
// println("response = \(response)")
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("\(responseString)")
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
println("response was not 200: \(response)")
return
}
}
if (error != nil) {
println("error submitting request: \(error)")
return
}
// handle the data of the successful response here
var result = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as? NSDictionary
//println(result)
}
task.resume()
}
PHP Code
print_r($_POST);
Output is
array(
)
But when I use
$data = json_decode(file_get_contents('php://input'), true);
It works fine
I dont know why $_POST is not working.
If your intent is actually to send a string, then you should change the content-type:
request.setValue("text/plain", forHTTPHeaderField: "Content-Type")
Tested your exact code with this modification on my tests server:
Otherwise, check #kekub's comment.
So I'm uploading a file from swift to a PHP server, the POST request arrives as expected with headers and all but I'm unable to get anything out of $_FILES. It's just an empty array.
I'm clearly doing something wrong on the Swift side, this is my code:
func testUpload(){
let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource("someTestFile", ofType: "zip")!
var data: NSData = NSData(contentsOfFile: path)!
var request = NSMutableURLRequest(URL: NSURL(string: "http://testsite.com/upload")!)
request.HTTPMethod = "POST"
let boundary = "----------ds2Gry67efddagdfsfhsHF"
let contentType = "multipart/form-data; boundary=\(boundary)"
request.setValue(contentType, forHTTPHeaderField:"Content-Type")
request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")
self.uploadFiles(request, data: data)
}
func uploadFiles(request: NSURLRequest, data: NSData) {
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
var task = session.uploadTaskWithRequest(request, fromData: data)
task.resume()
}
I'm pretty sure I'm missing something, I just can't figure out what it is...
POST method ,you need add header application/x-www-form-urlencoded