Swift 4 Codable Struct with Post Request - php

i want to send a url.request(POST)with a Codable Struct like That :
struct Picklist : Codable {
var id = Int()
var ean = String()
var position = String()
}
and my request is like that :
let request = NSMutableURLRequest(url: NSURL(string: "http://XXX.XX.XX.XX/NEW/index.php")! as URL)
request.httpMethod = "POST"
let myID = Picklist.init(id: 3, ean: "asdf", position: "q")
let encoder = JSONEncoder()
do {
let jsonData = try encoder.encode(myID)
request.httpBody = jsonData
print("jsonData: ", String(data: request.httpBody!, encoding: .utf8) ?? "no body data")
} catch {
print("ERROR")
}
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
}
task.resume()
and of the Server Side i have this PHP Script:
<?php
print_r($_POST);
?>
but i am receiving :
responseString = Optional(Array
(
[{"id":3,"ean":"asdf","position":"q"}] =>
)
my Problem is that i can't get the Keys with the value on my PHP..
what is wrong with the code ?

Finally, answer is :
if you want to work with the response string just go and decode the "data"
For example :
guard let data = data else {return}
do{
let realData = try JSONDecoder().decode(response.self, from: data)
completion(realData)
}catch let jsonErr{
print(jsonErr)
}
in realData you can work with the data, but you need to create Codable/decobale Struct to work with
response is my coddle/decodable struct
or :
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}

Related

Error with my Json request to PHP in Swift

this is my code for the Json request to php and to show the data in the app:
import Foundation
protocol FeedmodelProtocol: class {
func itemsDownloaded(items: NSArray)
}
class Feedmodel: NSObject, URLSessionDataDelegate {
weak var delegate: FeedmodelProtocol!
func downloadItems() {
let myUrl = URL(string: "http://www.example.net/zumba.php");
var request = URLRequest(url:myUrl!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "firstName=51&lastName=6";
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
self.parseJSON(data)
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
do{
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray;
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let stocks = NSMutableArray()
for i in 0 ..< jsonResult.count
{
print(jsonResult)
jsonElement = jsonResult[i] as! NSDictionary
let stock = Stockmodel()
//the following insures none of the JsonElement values are nil through optional binding
if let Datum = jsonElement["Datum"] as? String,
let Tankstelle = jsonElement["Tankstelle"] as? String,
let Kraftstoff1 = jsonElement["Kraftstoff1"] as? String,
let Preis1 = jsonElement["Preis1"] as? String,
let Kraftstoff2 = jsonElement["Kraftstoff2"] as? String,
let Preis2 = jsonElement["Preis2"] as? String,
let Notiz = jsonElement["Notiz"] as? String,
let longitude = jsonElement["longitude"] as? String,
let latitude = jsonElement["latitude"] as? String
{
print (Datum)
print(Tankstelle)
print(Kraftstoff1)
print(Preis1)
print(Kraftstoff2)
print(Preis2)
print(Notiz)
print(longitude)
print(latitude)
stock.Datum = Datum
stock.Tankstelle = Tankstelle
stock.Kraftstoff1 = Kraftstoff1
stock.Preis1 = Preis1
stock.Kraftstoff2 = Kraftstoff2
stock.Preis2 = Preis2
stock.Notiz = Notiz
stock.longitude = longitude
stock.latitude = latitude
}
stocks.add(stock)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: stocks)
})
}
}
I have a mySQL PHP what seems to work because my Console shows me that:
responseString = Optional("[\"51\",\"6\"]") (
51,
6 ) Could not cast value of type 'NSTaggedPointerString' (0x1045cbf68) to 'NSDictionary' (0x1045cc288). 2018-06-20
23:29:34.586355+0200 TankBilliger[37631:3753628] Could not cast value
of type 'NSTaggedPointerString' (0x1045cbf68) to 'NSDictionary'
(0x1045cc288). (lldb)
I don't know what the problem is, can anyone help?
Thank You!
The problem is , your getting data as dictionary but you taken as string
delete this line and try
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
This method parseJSON() do above functionality

Swift 3 problems Parsing json response

I am new on Swift but I was follwoing some examples like how to make a login app sending username and password fields to a php file and getting the json response back.
When I print my responseString I get:
[{"userid":1,"username":"rodrigo","password":"minhoca","groupname":"couple"}]
But when I try to parse the json I never can set the username variable because never gets into that part of the code, I just get "here"
Thanks for the help
func sendLoginInfo(username: String, password: String) -> String{
if let url = URL(string: "myphpurl"){
let request = NSMutableURLRequest(url:url)
request.httpMethod = "POST";// Compose a query string
let postString = "?username=\(myUsername)&password=\(myPassword)"
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("1\(error)")
}
else{
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("response string = \(responseString!)")
}
do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
// Print out dictionary
print(convertedJsonIntoDict)
// Get value by key
let firstNameValue = convertedJsonIntoDict["username"] as? String
print("here = \(firstNameValue!)")
}
else{
print("here")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
task.resume()
}
return ""
}
Change the NSDictionary to NSArray in your code because you are getting an array and trying to convert to dictonary:
if let convertedJson = try JSONSerialization.jsonObject(with: data!, options: []) as? NSArray
get the object at index 0 which will give you dictonary & then you can get username
So the Final code will be:
func sendLoginInfo(username: String, password: String) -> String{
if let url = URL(string: "myphpurl"){
let request = NSMutableURLRequest(url:url)
request.httpMethod = "POST";// Compose a query string
let postString = "?username=\(myUsername)&password=\(myPassword)"
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("1\(error)")
}
else{
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("response string = \(responseString!)")
}
do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data!, options: []) as? NSArray {
// Print out dictionary
print(convertedJsonIntoDict)
// Get value by key
let firstNameValue = (convertedJsonIntoDict[0] as! NSDictionary)["username"] as? String
print("here = \(firstNameValue!)")
}
else{
print("here")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
task.resume()
}
return ""
}

Return contents of url after posting login in Swift?

So I've got a few lines that will "login" to the web page, and they fetch the contents and print them to the console, but I can't figure out how to get the results out of the "task" and use them later on in the code.
let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8888/mobilelogin.php")!)
request.HTTPMethod = "POST"
let username = email_input.text;
let password = password_input.text;
var postString = "username="
postString += username!
postString += "&password="
postString += password!
print(postString);
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
print(request.HTTPBody);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in guard error == nil && data != nil
else {
// check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
// check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print("responseString = \(responseString)");
return
}
print("This is the task string")
task.resume()
You can't return from a closure, you need to use a "callback".
We make a function for your code:
func getData(username username: String, password: String)
but instead of adding a return type, we add a callback, here named "completion":
func getData(username username: String, password: String, completion: (response: String)->()) {
}
And inside the function, we use this callback at the location where the data will be available:
func getData(username username: String, password: String, completion: (response: String)->()) {
let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8888/mobilelogin.php")!)
request.HTTPMethod = "POST"
var postString = "username="
postString += username
postString += "&password="
postString += password
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard let data = data where error == nil else {
fatalError(error!.debugDescription)
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
print("response = \(response)")
fatalError("statusCode should be 200, but is \(httpStatus.statusCode)")
}
guard let str = String(data: data, encoding: NSUTF8StringEncoding) else {
fatalError("impossible to get string from data")
}
completion(response: str)
}
task.resume()
}
And you will use it like this:
getData(username: email_input.text!, password: password_input.text!) { (response) in
print(response)
}

POST json object in a form variable on a sever

hello I am working on IOS SWIFT 2. I NEED to send the json object in a variable so that I can access the json object like that
$json = $_POST['json'];
$data = json_decode($json, TRUE);
$email = $data['email'];
$user_password = $data['password'];
right now the data is posting on server like this
{
"email" : "email",
"password" : "password"
}
This is the code I am using
func post() {
let url:String = "http://example.com/test.php"
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
let params = ["email":"email", "password":"password"] as Dictionary<String, String>
//let request = NSMutableURLRequest(URL:url)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
do {
let data = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)!
print("dataString is \(dataString)")
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
} catch {
//handle error. Probably return or mark function as throws
print(error)
return
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
// handle error
guard error == nil else { return }
print("Response: \(response)")
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)")
let json: NSDictionary?
do {
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
} catch let dataError {
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
print(dataError)
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
// return or throw?
return
}
// 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
let success = parseJSON["success"] as? Int
print("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)
print("Error could not parse JSON: \(jsonStr)")
}
})
task.resume()
}
I want to pass the json above in a form variable called 'json'.
I would highly recommend using a Library, such as Alamofire to handle this.
Doing it yourself is tedious.
Once added to your Swift Project, you can send JSON parameters really, really elegantly:
Example from the Github page:
let parameters = [
"foo": [1,2,3],
"bar": [
"baz": "qux"
]
]
Alamofire.request(.POST, "https://httpbin.org/post", parameters: parameters, encoding: .JSON)
Then you can use your existing PHP code to process your JSON.
Edit:
Also handling JSON is really elegant too:
Alamofire.request(.POST, url, etc).responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}

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