iOS Swift POST param and body - ios

I'm trying to POST a key parameter and a JSON dictionary body to an API but for some reason it won't work.
Here's my work so far.
#IBAction func POST(_ sender: Any) {
let url = URL(string: "http://apilink.com/updateProfile&=param")!
let jsonObject = ["FName":"Tarik",
"LName":"Salama"]
let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject, options: [])
var request = URLRequest(url: url)
request.httpMethod = "post"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("error:", error)
return
}
do {
guard let data = data else { return }
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject] else { return }
print("json:", json)
} catch {
print("error:", error)
}
}
task.resume()
}
I get this error when I click the POST button:
error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
What am I doing wrong?
I tried changing some stuff around after I checked some other threads like putting the parameter and the data dictionary into a key:value dictionary but the API responded and said that the data is invalid which means the whole thing was sent in an incorrect format.
Note: I'm not allowed to use 3rd party libraries like Alamofire and the API link is working fine as shown in the screenshot.

you can check the problem by printing the response data
do {
guard let data = data else { return }
print(String(data: data, encoding: .utf8) ?? "No Conversion") //Print Here
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject] else { return }
print("json:", json)
} catch {
print("error:", error)
}
look at the 'Print Here' line. I believe the response is not a valid json so when you try to parse the data to JSOn it always ends up in catch block.

Related

Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 1." UserInfo={NSDebugDescription=Invalid value around character 1. swift 4

I got response from api via postman
{
"status": "1",
"error": false,
"message": "Your order has been placed successfully"
}
I called api and pass the params which required to call api. The code is giving an error "Invalid value around character 1."
let urlsContainer = UrlsContainer()
let url = URL(string: urlsContainer.allotRunnerAPI)
let session = URLSession.shared
var request = URLRequest(url: url!)
let postString = "user_id=\(user_id)&pincode=\(pincode)&select_address=\(select_address)&store_id=\(store_id)"
request.httpMethod = "POST"
request.httpBody = postString.data(using: .utf8)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
The code should execute the do block of code
do {
let parsedData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: AnyObject]
print(parsedData)
}
but now because of some problem in code it is executing catch block of code
catch let error {
print(error)
}
})
task.resume()
I am not able to find the problem in my code to resolve the error
use [String:String] to send data to api
let params = ["user_id":user_id,
"pincode":pincode,"select_address":select_address,
"store_id":store_id]
let data = JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
post this data as your body

JSON text did not start with array error in JSONSerialization Swift

I am getting the following error when performing the request below.
Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start
with array or object and option to allow fragments not set."
UserInfo={NSDebugDescription=JSON text did not start with array or
object and option to allow fragments not set.}
#IBAction func onPostTapped(_ sender: Any) {
let parameters = ["Name": "Yogesh", "Mobile": "1212121212", "DOB": "1122/12/12", "Address": "qwqwqwqw"]
//https://jsonplaceholder.typicode.com/posts
guard let url = URL(string: "http://localhost/webservice/Register.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(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
What could be causing this issue?
The error explains the issue, the JSON received doesn't start with an object or an array and Allow Fragments is not set.
Check your JSON is what you would expect to receive
You can enable allow fragments like so..
try JSONSerialization.jsonObject(with: data, options: .allowFragments)
Allow fragments allows you to load partial JSON data that does not map directly to an array or Dictionary
From the docs:
Specifies that the parser should allow top-level objects that are not
an instance of NSArray or NSDictionary.

unable to download json data too large in swift

I tried downloading data to JSON from a webserver that accepts username and password input in a json format. Once I have authenticated, I have to download json data. So I used this method
let postString = ["user":"user1", "pwd": "pass1"]
var request = URLRequest(url:URL(string:"http://vdctest.agrishare.com/list_up")!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("application-idValue", forHTTPHeaderField: "secret-key")
request.httpBody = try! JSONSerialization.data(withJSONObject: postString, options:.prettyPrinted)
let session = URLSession.shared
//Post
session.dataTask(with: request){data, response, err in
//Guard: ws there error ?
guard(err == nil) else {
print("err")
return
}
//Guard: check was any data returned?
guard let data = data else{
print("no data return")
return
}
//Convert Json to Object
let parseResult: [String:AnyObject]!
do{
parseResult = try JSONSerialization.jsonObject(with: data, options:.allowFragments) as! [String:AnyObject]
print("\(parseResult)")
} catch {
print("Could not parse data as Json \(data)")
return
}
//Check jsonDictionary
guard let jsonArray = parseResult["success"] as? [String:AnyObject] else{
print("jsonDictionary error")
return
}
//check jsonArray and switch to LoginViewController
if(jsonArray.count == 0 ){
print("jsonArray not found")
return
} else{
DispatchQueue.main.async{
let loginvc = LoginViewController()
self.present(loginvc, animated: true, completion: nil)
print(jsonArray)
}
}
}.resume()
}
When I run the app, the terminal says:
Could not parse data as Json 1520 bytes
Why?
Output:
Could not parse data as Json: Error Domain=NSCocoaErrorDomain
Code=3840 "Invalid value around character 0."
UserInfo={NSDebugDescription=Invalid value around character 0.}
You likely do not have valid JSON -- as the error states, right around the very first character. Valid JSON is going to either be a single Object that opens and closes with a { and } or an Array of Objects, opening and closing with a [ and ].
Please post a bit of the returned JSON to confirm.
EDIT: Also -- if you are requesting an http resource, and not https, you need to add the server to the allowed unsecure servers list.

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 to parse data from server? [duplicate]

This question already has answers here:
Correctly Parsing JSON in Swift 3
(10 answers)
Closed 5 years ago.
I am getting data like {"OTP":"5480"} in a string named responseString, How can I uset it.
My Code is.
#IBAction func signupButton() {
var request = URLRequest(url: URL(string:"http://122.166.215.8:8090/RESTMVC/validateMobileNumber")!)
request.httpMethod = "POST"
let mobileNumberString : String = self.mobileNumberTextfield.text!
let postString = ["mobileNumber":mobileNumberString]
request.httpBody = try! JSONSerialization.data(withJSONObject: postString, options:.prettyPrinted)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
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=\(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 = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
var recived = [UInt8]()
recived.append(contentsOf: data)
print(responseString!)
DispatchQueue.main.async(execute: {
self.performSegue(withIdentifier: "OTPView", sender: nil)
});
}
task.resume()
}
and I want to change that string into Array. Or is there any way in which I can get Array directly on the place of String?
To access value of "OTP" you need to parse your response string and convert it in Json dictionary you can achive this using following code, just pass your response data in JSONSerialization.jsonObject(with: data, options: .allowFragments)
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! Dictionary<String, Any>
if let otpValue = json["OTP"] {
print("Otp value : \(otpValue)")
}
} catch {
// Handle Exception
}
You can get otp from dictionary like below.
print(responseString["OTP"])

Resources