How to convert json into byte format in swift? - ios

I am working on a app that will take a users name and password, authenticate it and log them in. So what I am doing is taking the inputs and converting them into JSON. But before I send it they need to be in byte format for it to work.
So far this is what I have.
#IBOutlet var name: UITextField!
#IBOutlet var password: UITextField!
let json: [String: AnyObject] = ["name:": name.text! as AnyObject,
"password:": password.text! as AnyObject]
do{
let jsonData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
//this is just an example website
let url = URL(string: "https://example.com")
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request as URLRequest) {(data, response, error) in
guard error == nil else {
print(error)
return
}
let JSON = try! JSONSerialization.jsonObject(with: jsonData, options: .allowFragments)
print(JSON)
}
task.resume()
} catch {
print(error)
}
I know there is something called JSON marshaling but not sure if that exist in Swift.
How do I convert the JSON file into byte format in Swift?

Related

How to add post api request in parameters while parsing in swift

This is my api request:
{
"billDetails": {
"billerId":"EPDCLOB00AN232",
"customerParams":[{"name":"Service Number","value":"116515M025033"}]
}
}
here is code:
func billerFetchService(){
let parameters = ["billDetails": {
"billerId" : "EPDCLOB00ANP01",
"customerParams" : [{"name":"Service Number","value":"116515M025007621"}]
}
] as [String : Any]
let url = URL(string: "https://app.com/Fetch/fetch")
var req = URLRequest(url: url!)
req.httpMethod = "POST"
req.addValue("application/json", forHTTPHeaderField: "Contet-Type")
req.addValue("application/json", forHTTPHeaderField: "Accept")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else {return}
req.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: req, completionHandler: {(data, response, error) in
if response != nil {
// print(response)
}
if let data = data {
do{
var json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
print("fetching json \(json)")
}catch{
print("error")
}
}
}).resume()
}
if i add like this in parameters error
Consecutive statements on a line must be separated by ';'
Insert ';'
Expected expression
Where i did mistake, please help me in code
You need
let parameters = ["billDetails": [
"billerId" : "EPDCLOB00ANP01",
"customerParams" : [["name":"Service Number","value":"116515M025007621"]]]]
Please make your parameter as this
let parameters = ["billDetails":
[
"billerId": "EPDCLOB00ANP01",
"customerParams" : ["name":"Service Number","value":"116515M025007621"]
]
] as [String : Any]

Swift HTTP Post Request returns HTML of site instead of JSON response

I am trying to reach a site that should take the username and password given and return a JSON which contains information stating whether or not the login data provided was valid or not.
However, all I'm getting back is the site's HTML code instead of a response. I've tried the request with the same parameters on https://www.hurl.it/ and have gotten the correct response so that does not seem to be the issue.
I use the following code:
private func uploadToAPI(username: String, password: String) {
guard let url = URL(string: "http://api.foo.com/login.php"),
let encodedUsername = username.addingPercentEncoding(withAllowedCharacters: CharacterSet.alphanumerics),
let encodedPassword = password.addingPercentEncoding(withAllowedCharacters: CharacterSet.alphanumerics) else {
self.loginButton.isLoading = false
return
}
let httpBodyParameters = ["user": encodedUsername, "password": encodedPassword, "client": "ios", "version": "5"]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject: httpBodyParameters, options: JSONSerialization.WritingOptions.prettyPrinted)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
URLSession.shared.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response.mimeType) // Prints "text/html"
}
if let data = data {
print(try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments)) // Prints nil
print(String(data: data, encoding: String.Encoding.utf8)) // Prints the site's HTML
}
}.resume()
}
I fail to see where the issue is. I've also tried not setting the HTTP headers but that makes no difference. Anyone got any ideas?
It seems like not setting the HTTP header fields and using a string literal instead of a Dictionary as HTTP body data did it for me.
For anyone interested this is the code that now receives the expected response:
guard let url = URL(string: "http://api.foo.com/login.php?"),
let encodedUsername = username.addingPercentEncoding(withAllowedCharacters: CharacterSet.alphanumerics),
let encodedPassword = password.addingPercentEncoding(withAllowedCharacters: CharacterSet.alphanumerics) else {
if let delegate = self.delegate {
delegate.viewModelDidRejectLogin(self)
}
return
}
let httpBodyString = "user=\(encodedUsername)&password=\(encodedPassword)&client=ios&version=5"
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = httpBodyString.data(using: String.Encoding.utf8)
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else {
print(error)
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String : AnyObject] {
self.readLoginResponse(json)
}
} catch {
print(error)
}
}.resume()

Feedback json format wrong

This is my feedback json string:
{"name":"abc", "cardNumber":"1234567890", "data": [{A data},{B data}...]}
I use this function to send data, then get json and encode:
func uploadData(word:String){
var request = URLRequest(url: url!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 30)
request.httpMethod = "POST"
request.httpBody = word.data(using: .utf8)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession(configuration: URLSessionConfiguration.default)
session.dataTask(with: request, completionHandler: {(data, response, error) in
if let data = data{
do{
let data = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers)
print(data) //I want to know what is this so I print
}catch{
print(error.localizedDescription)
}
}
}).resume()
}
But the console always says:The data couldn't be read because it isn't in the correct format
This json can be format and read in android if I use JSONObject.getJSONArray("myValue")...
I try to use print(data)(without json encode) to show if there is any data in feedback and I get 400byte in console, so I'm sure there is data send back to me.
UPDATE 12/28:
{"name":"abc",
"cardNumber":"1234567890",
"data": [{day:20171228, time: 09:10:11},
{day:20171226, time: 20:00:12},
{day:20171227, time: 15:30:22}
]
}
I'm sure this json can be read in android, the receiver and sender I use is vb.net, it use sendingString = JsonConvert.SerializeObject(JSONClass) to become json string, then convert to byte to send out.
UPDATE 12/28 new
After trying so much, I found string can get the feedback, but the value of name is Chinese word, other value is English and number, only name is unreadable, now I'm checking which String.Encoding will work, then if I encode it success, I will try to format to json Array.
Can you try this one?
func uploadData(word:String){
var request = URLRequest(url: url!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 30)
request.httpMethod = "POST"
request.httpBody = word.data(using: .utf8)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession(configuration: URLSessionConfiguration.default)
session.dataTask(with: request, completionHandler: {(data, response, error) in
if let data = data{
if let returnData = String(data: data!, encoding: .utf8) {
print(returnData)
} else {
print("Invalid Data Coming")
}
do{
let data = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject]
print(data) //I want to know what is this so I print
}catch{
print(error.localizedDescription)
}
}
}).resume()
}

HTTP POST (IOS)

I need to do an HTTP POST for a page that simply returns a literal (which can be "OK" or "ERROR") I have a web tutorial that shows how to do this and it returns a JSON, I follow the tutorial and it works perfectly .
My problem is exactly there ... it returns a JSON and what my site returns is not a JSON but a simple literal ..
How do I get this literal that the site is returning ... I've tried several changes in the code below but without success.
let parameters = ["username": "#kilo_loco", "tweet": "HelloWorld"]
guard let url = URL(string: "http://xxxxxxxxxx.com/ola.php") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
//request.addValue("application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else { return }
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print ("*******")
print(response)
}
//print(data as Any)
if let data = data {
print("** TESTE **")
print(data)
//do {
// let json = try JSONSerialization.jsonObject(with: data, options: [])
//print(json)
//} catch {
// print(error)
// }
}
}.resume()
The Last "Print (data) returns the size in bytes and not the contents of the literal ..
You are missing parse Data to JSON Object, I think you have that code almos there but commented
do {
let json:AnyObject? = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json{
print(parseJSON)
}
}
Hope this helps you

How can i get the data from string in desired formate to have data of NSData type

func callAddWithPOST(Name mname:String, PhoneNo mphone:String, Email memail:String, Comment mcomments:String)
{
var names = [String]()
let login = ["countryId":"1"]
print("Your Result is : = \(login)")
let url = NSURL(string: "http://photokeeper.mgtcloud.co.uk/commonwebservice.asmx/getStateList")!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
do
{
let auth = try NSJSONSerialization.dataWithJSONObject(login, options: .PrettyPrinted)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
request.HTTPBody = auth
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let responseString = String(data:data!, encoding: NSUTF8StringEncoding)
let validresponseString = "\(responseString!)"
print(validresponseString)
let badJsonString = "This really isn't valid JSON at all"
let jsonData = validresponseString.dataUsingEncoding(NSUTF8StringEncoding)!
let badJsonData = badJsonString.dataUsingEncoding(NSUTF8StringEncoding)!
do
{
let parsed = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments)
let otherParsed = try NSJSONSerialization.JSONObjectWithData(badJsonData, options: NSJSONReadingOptions.AllowFragments)
}
catch let error as NSError
{
print("Done.")
}
})
task.resume()
}
catch
{
print("Error")
}
}
I am in search of one solution for fetching the desired data from this method,i want to display StateID and StateName from this string data. i can not convert the string "responseString" in NSData to have this string as NSData to fetch the desired record. Will any body please help me to fix this issue.
If you want to get the value for key from a json you should convert the json to Dictionary with this code:
Swift 3
JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject]
Swift 2
NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String:AnyObject]
let me know in the comments if I misunderstood something before the downvote, thank you.

Resources