swift PUT API from json object - php

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 **********/
}

Related

Swift - Send array to PHP

I want to send an array to my server with URLRequest post method but it doesn't work.
When I send a string it works well but with an array not work. I can't get data with array post.
Below code works great:
func getData() {
pageid = 1
var request = URLRequest(url: URL(string: "http://localhost/index.php")!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60)
request.httpMethod = "POST"
let postString = "page=" + String(pageid);
request.httpBody = postString.data(using: .utf8)
URLSession.shared.dataTask(with:request, completionHandler: {(data, response, error) in
do {
let response = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
let itemsArray = response["items"] as! [AnyObject]
for itemObj in itemsArray {
print(itemObj)
}
} catch {
}
}).resume();
}
my array is:
var ids: [Int] = [1, 5, 8]
i try to send it like this but it doesn't work
let postString = "page=" + String(ids.description)
my php code:
<?php
$pageid = $_POST['page'];
....
?>

Make a Swift 5 function with completionHandler to print JSON data

I have the following Swift 5 function that calls a PHP script on my server:
func getJSONdata(fileName:String, completion: (_ json:JSON)->()) {
let session = URLSession(configuration: .ephemeral)
var jsonData = JSON()
let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
DispatchQueue.main.async {
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil {
print("\(error!.localizedDescription)")
return
}
// Get data
jsonData = try! JSON(data: data!)
// print(jsonData)
}
task.resume()
}// ./ dispatch aync
completion(jsonData)
}
This function is hosted in a separate Swift file, now in my ViewController.swift I call that function as follows:
getJSONdata(fileName: "Users") { (jsonData) in
print("\(jsonData)")
}
In this case, I'm getting an empty array in my Xcode console, instead, if I uncomment the // print(jsonData) that's inside my getJSONdata() function, the console prints out my JSON data.
Obviously I'm doing something wrong in my getJSONdata() function because I cannot retrieve data by calling in ViewController.swift.
Where is the error in my function?
Try the below code. Maybe it will help you.
func getJSONdata(fileName:String, completion:#escaping (_ json:JSON)->()) {
let session = URLSession(configuration: .ephemeral)
var jsonData = JSON()
let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
DispatchQueue.main.async {
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil {
print("\(error!.localizedDescription)")
completion(nil)
}
// Get data
jsonData = try! JSON(data: data!)
// print(jsonData)
completion(jsonData)
}
task.resume()
}
}
I've found a solution, I don't know why but if I add #escaping to my function declaration, it works fine.
I also had to move completion(jsonData) below jsonData = try! JSON(data: data!), as suggested by #chirag90.
So, here's the complete function:
func getJSONdata(fileName:String, completion: #escaping (_ json:JSON?) -> Void) {
let session = URLSession(configuration: .ephemeral)
var jsonData = JSON()
let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
DispatchQueue.main.async {
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil {
self.simpleAlert("\(error!.localizedDescription)")
return
}
// Get data
jsonData = try! JSON(data: data!)
completion(jsonData)
}
task.resume()
}// ./ dispatch aync
}

Swift 3 Garbage at End

I am trying to receive info from my server but I keep getting the error telling me that there is Garbage at the end. It could be that the file being passed from the server has HTTP info as well but I do not know how to get rid of it. Here is my code:
class ViewController: UIViewController {
//URL to our web service
let URL_SAVE_TEAM = "http://<IP Address>/WebServerTest/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! as URL)
//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.data(using: String.Encoding.utf8);
//creating a task to send the post request
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
if error != nil{
print("error is \(error)")
return;
}
//parsing the response
do {
//converting resonse to NSDictionary
let myJSON = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) 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()
}
I am unable to see the issue.

Swift - Send an array as POST request parameter to PHP

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!

Empty array when making a HTTP Post Request to PHP from Swift App

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.

Categories