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
Related
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 have a function that send two string values "Name and Text" to a server.
When the post method is sent the php file send an email with this two values.
Everything works if I send only one value from my iOS app however, if I try to send two or more value I don't get any email.
The code I am using is:
func postToServerFunction() {
var textFromapp: NSString = sendValueText.text
var nameFromapp: NSString = sendValueName.text
println("Button Pressed")
var url: NSURL = NSURL(string: "http://example.com//iOS/send_ios.php")!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
var bodyData = "data=" + (textFromapp as String) //data to send
var bodyName = "name=" + (nameFromapp as String) //data to send
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
request.HTTPBody = bodyName.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
println(response)
if let HTTPResponse = response as? NSHTTPURLResponse {
let statusCode = HTTPResponse.statusCode
if statusCode == 200 {
// Yes, Do something.
}
}
}
}
How could I tell the HTTPBody to look at both values?
for Future reference here how I solved it:
var bodyData = "data=" + (textFromapp as String) + "&name=" + (nameFromapp as String)
any other suggestion is welcome
Look at this answers. Fun(ctional) is the most beautiful.
function encodeData(data) {
return Object.keys(data).map(function(key) {
return [key, data[key]].map(encodeURIComponent).join("=");
}).join("&");
}
I cannot get the parameter sent from the swift code. If i ignore the parameter i can got return result. Please help. THX
Swift Code:
var url: NSURL = NSURL(string: urlPath)!
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.timeoutInterval = 60
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
var searchString = ""
var bodyData: NSString = "brandCode=BU&model=test1234"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding)
var connection:NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)!
connection.start()
PHP Code:
$brandCode=$_POST['brandCode'];
$model=$_POST['model'];
$cnx=odbc_connect('testODBC','testing','testing');
$sql="select * from brand where brand='".$brandCode."' and model='".$model."'";
$cur= odbc_exec($cnx, $sql);
while($info = odbc_fetch_array($cur))
{
$resultArray[]=array($info);
}
echo json_encode($resultArray);
Try with this code
var URL: NSURL = NSURL(string: "http://example.com")
var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
var bodyData = "brandCode=BU&model=test1234"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
I'm not very strong in PHP, but it looks to me like you are trying to extract the model value as an URL parameter rather than from the body of the message.
You should either append your "brandCode=BU&model=test1234" string directly to your URL:
http://myurl.php?brandCode=BU&model=test1234
Or build the URL using NSURLComponents.
Adding parameters to the URL is different then transmitting data in the body of A POST.
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?
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.