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.
Related
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
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.
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
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.
I'm simply trying to send a JSON string via a Swift3 httprequest.
Tried using a Dictionary, and an escaped string ...
func getToken(successHandler: #escaping (Any) -> Void, errorHandler: #escaping (Any) -> Void) {
var request = URLRequest(url: URL(string: "http://my-api.domain.com/getToken")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do
{
// try with Dictionary
let bodyJson: [String: String] = [
"username": "theusername"
]
let bodyJsonData = try JSONSerialization.data(withJSONObject: bodyJson, options: [])
// try with escaped String
let jsonString = "{" +
"\"username\": \"theusername\"," +
"}"
let jsonStringData = jsonString.data(using: String.Encoding.utf8)
//request.httpBody = bodyJsonData
request.httpBody = jsonStringData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
print(error)
errorHandler(error)
return
}
guard let data = data else {
print("Data is empty")
errorHandler("Data is empty")
return
}
var json: Any? = nil
do
{
json = try JSONSerialization.jsonObject(with: data, options: [])
DispatchQueue.main.asyncAfter(deadline: .now()) {
successHandler(json)
}
}
catch let error as NSError {
errorHandler(error)
}
}
task.resume()
}
catch
{
errorHandler(error)
}
}
I keep getting:
Handle 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.}
I can't find how to try allowing fragments, all of the examples/tutorials are for Swift2.x :/
Unsure what to do!
// prepare json data
let mapDict = [ "1":"First", "2":"Second"]
let json = [ "title":"ABC" , "dict": mapDict ] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
// create post request
let endpoint: String = "https://yourAPI"
let session = URLSession.shared
let url = NSURL(string: endpoint)!
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
let task = session.dataTask(with: request as URLRequest){ data,response,error in
if error != nil{
print(error?.localizedDescription)
return
}
}
task.resume()
} catch {
print("bad things happened")
}