iOS: Unable to convert Json String to Array in swift? - ios

In my project I want to convert Json String from server to Array but Unable to convert, But when I hard code(Directly gave the particular json string) the json string means that will be convert. Please help me to find the issue..
Here I gave the code what i am tried.
var params = NSMutableDictionary()
params = [
"inspectionLogId": inspectionLogIdStr
]
let manager = AFHTTPSessionManager()
manager.requestSerializer = AFJSONRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/plain", "text/html", "application/json"]) as Set<NSObject> as Set<NSObject>! as! Set<String>?
manager.requestSerializer.setValue("", forHTTPHeaderField: "apptoken")
manager.requestSerializer.setValue(strAppToken, forHTTPHeaderField: "token")
let urlString:NSString = NSString(format: "%#%#", ApiConstantFile().baseUrlProperty,ApiConstantFile().getTemplateDataUrl)
print(urlString)
manager.get(urlString as String, parameters: params, progress: nil, success: {
(operation, responseObject) in
self.stopAnimation()
let jsonstring = String(data: responseObject! as! Data, encoding: String.Encoding.utf8)
print("jsonstring is:, \(jsonstring!)")
let data = jsonstring!.data(using: .utf8)!
print(data)
do {
if (try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>]) != nil {
let jsonArray = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as! [Dictionary<String,Any>]
print(jsonArray)
} else {
print("bad json")
}
} catch {
print(error)
}
}, failure: {
(operation, error) in
self.stopAnimation()
print(error)
self.alert(message: error.localizedDescription)
})
when I print the json string means they show to string:
"[{\"propertyId\":\"1\",\"inspectionTemplateId\":1118,\"value\":[{\"widgetControllerId\":141,\"value\":\"Flood Summary Name\"},{\"widgetControllerId\":142,\"value\":\"Did the property flood?\"},{\"widgetControllerId\":143,\"value\":\"no\"}]}]"
But when I directly gives the string means it will convert to array.
let jsonstring = "[{\"propertyId\":\"1\",\"inspectionTemplateId\":1118,\"value\":[{\"widgetControllerId\":141,\"value\":\"Flood Summary Name\"},{\"widgetControllerId\":142,\"value\":\"Did the property flood?\"},{\"widgetControllerId\":143,\"value\":\"no\"}]}]"

Just replace AFHTTPResponseSerializer with AFJSONResponseSerializer like this:
var params = NSMutableDictionary()
params = [
"inspectionLogId": inspectionLogIdStr
]
let manager = AFHTTPSessionManager()
manager.requestSerializer = AFJSONRequestSerializer()
manager.responseSerializer = AFJSONResponseSerializer()
manager.requestSerializer.setValue("", forHTTPHeaderField: "apptoken")
manager.requestSerializer.setValue(strAppToken, forHTTPHeaderField: "token")
let urlString:NSString = NSString(format: "%#%#", ApiConstantFile().baseUrlProperty,ApiConstantFile().getTemplateDataUrl)
print(urlString)
manager.get(urlString as String, parameters: params, progress: nil, success: {
(operation, responseObject) in
self.stopAnimation()
print(responseObject)
}, failure: {
(operation, error) in
self.stopAnimation()
print(error)
self.alert(message: error.localizedDescription)
})

Related

How to avoid "Error Domain=NSCocoaErrorDomain Code=3840" in Swift?

I keep getting this particular error when trying to parse a JSON response in Swift:
Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}
Code:
let dict = [
"phone": phone,
"firstname": "\(String(describing: firstName))",
"lastname": "\(String(describing: lastName))"
]
as [String: Any]
if let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: []) {
var request = URLRequest(url: URL(string: "\(config.baseURL)employee")!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
request.timeoutInterval = 30.0
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if error != nil {
DispatchQueue.main.async {
self.alertController.singleButtonAlertController("Error", (error?.localizedDescription)!, self, self.defaultAction)
return
}
}
guard let data_ = data else {
return
}
do {
let jsonObj = try JSONSerialization.jsonObject(with: data_, options: .mutableContainers) as? NSDictionary
guard let parseJSON = jsonObj else {
return
}
self.navigationItem.rightBarButtonItem = self.rightBarButton
let meta = parseJSON["meta"] as? [String:Any]
let status = meta!["status"] as? String
if status == "200" {
isEmployeeModified = true
self.dismiss(animated: true, completion: nil)
} else {
let info = meta!["info"] as? String
let message = meta!["message"] as? String
DispatchQueue.main.async {
self.alertController.singleButtonAlertController(info!, message!, self, self.defaultAction)
}
}
} catch let error as NSError {
print(error)
}
}
task.resume()
I have used similar codes in other parts of the project and everything checks out.
According to this Error, the response from your server is not a valid JSON
Can you use responseString instead of responseJSON like below
Alamofire.request(URL, method: requestMethod, parameters: params).responseString{ response in
print(response)
}
I was able to figure out what was wrong and I'm going to explain this here for future readers. Apparently, I was doing a GET request the wrong way, so when I intend to do a POST request, for some reason, it still sees it as a GET request and that was why I kept getting the response: Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}
Below is my refactored code and it works without any hassle:
let dict = [
"phone": phone,
"firstname": firstName,
"lastname": lastName
] as [String : Any]
guard let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: []) else {
return
}
guard let url = URL(string: "\(config.baseURL)employee") else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData as Data
request.timeoutInterval = 10
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print("JSON Response: \(response)")
}
if error != nil {
DispatchQueue.main.async {
self.navigationItem.rightBarButtonItem = self.rightBarButton
self.alertController.singleButtonAlertController("Error", (error?.localizedDescription)!, self, self.defaultAction)
return
}
}
if let data = data {
do {
let parseJSON = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary
let meta = parseJSON!["meta"] as? [String:Any]
let status = meta!["status"] as? String
if status == "200" {
isEmployeeModified = true
self.dismiss(animated: true, completion: nil)
} else {
let info = meta!["info"] as? String
let message = meta!["message"] as? String
DispatchQueue.main.async {
self.alertController.singleButtonAlertController(info!, message!, self, self.defaultAction)
}
}
} catch {
print(error)
}
}
}.resume()

How to send json as parameter iOS swift?

I want to send following object as body parameter. But serialization is failing:
{
"StartAddress":"Colombo",
"EndAddress":"Kandy",
"DepartureAddress":"Kollupitiya, Colombo",
"ArrivalAddress":"Peradeniya, Kandy",
"CreatedDate":"2017-07-30",
"Date":"2017-07-30",
"Time":"2017-07-30",
"IsLadiesOnly":true,
"IpAddress":"fe80::8638:38ff:fec8:ea50%wlan0",
"Country":"Srilanka",
"VehicleId":"1129",
"StartLocation":[
6.9270974,
79.8607731
],
"EndLocation":[
7.2916216,
80.6341326
],
"Points":"k}gi#y{lf",
"Route":{
"Bounds":{
"NorthEast":[
7.2916216,
80.6341326
],
"SouthWest":[
6.9270974,
79.8607731
]
},
"Legs":[
{
"LegId":1,
"Distance":14904,
"Duration":1941,
"StartAddress":"Colombo",
"EndAddress":"Kadawatha",
"StartLocation":[
6.9270974,
79.8612478
],
"EndLocation":[
7.0011125,
79.95000750000001
],
"Ancestors":[
],
"Price":745
},
{
"LegId":2,
"Distance":63040,
"Duration":6209,
"StartAddress":"Kadawatha",
"EndAddress":"Kegalle",
"StartLocation":[
7.0011125,
79.95000750000001
],
"EndLocation":[
7.251436200000001,
80.3466076
],
"Ancestors":[
"Colombo"
],
"Price":3152
},
{
"LegId":3,
"Distance":38990,
"Duration":4430,
"StartAddress":"Kegalle",
"EndAddress":"Kandy",
"StartLocation":[
7.251436200000001,
80.3466076
],
"EndLocation":[
7.2901864,
80.6338425
],
"Ancestors":[
"Colombo",
"Kadawatha"
],
"Price":1950
}
]
},
"TotalPrice":"5847.0",
"SeatCount":1,
"Detour":1,
"Luggage":2,
"DetoursDescription":"10 Minutes",
"LuggageDescription":"Small Luggage",
"Notes":"new ride"
}
when I try to serialize it before send it gives an error:
'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization
dataWithJSONObject:options:error:]: Invalid top-level type in JSON
write'
func synchronusPostRequstWithHeadersJson(apiMethod:String, params:JSON, headers:[ String: String]) -> ResultModel {
let resultModel = ResultModel()
//create the url with URL
let url = URL(string: BASE_URL + apiMethod )!
let session = URLSession.shared
//// **** HERE IT FAILING *****////
let jsonData = try? JSONSerialization.data(withJSONObject: params)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
for item in headers {
request.addValue(item.value, forHTTPHeaderField: item.key)
}
let semaphore = DispatchSemaphore(value: 0)
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
if(error != nil){
resultModel.ErrorType = .NO_INT
resultModel.JsonReslut = JSON.null
}else{
if let resp = response as? HTTPURLResponse{
if(resp.statusCode == 200){
if let jsonResult = JSON(data) as? JSON {
resultModel.ErrorType = .NO_ERROR
resultModel.JsonReslut = jsonResult
}
}else{
if let jsonResult = JSON(data) as? JSON {
resultModel.ErrorType = .SEREVR_ERROR
resultModel.JsonReslut = jsonResult
}else{
resultModel.ErrorType = .SEREVR_ERROR
resultModel.JsonReslut = JSON.null
}
}
}
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
return resultModel
}
How can i send that request?. Is it possible with alamofire?
Using Almofire you can achieve this as
let params: [String: Any] = [
"StartAddress":"Colombo",
"EndAddress":"Kandy",
"DepartureAddress":"Kollupitiya, Colombo",
"StartLocation":[
6.9270974,
79.8607731
],
"EndLocation":[
7.2916216,
80.6341326
],
] //Do check your dictionary it must be in correct format
Alamofire.request("yourUrl", method: .post, parameters: params, encoding: JSONEncoding.default)
.responseJSON { response in
print(response)
}
try using:
let session = Foundation.URLSession.shared
let url = URL(string: "Your server url")
var request = URLRequest(url : url!)
request.httpMethod = "POST"
let params :[String:Any] = ["name":"yuyutsu" as Any,"rollno":12 as Any] //Add your params
do {
let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
session.dataTask(with: request, completionHandler: { data, response, error in
OperationQueue.main.addOperation {
guard error == nil && data != nil else { // check for fundamental networking 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: String.Encoding.utf8)
print("responseString = \(responseString!)")
if let responsedata = responseString!.data(using: String.Encoding.utf8)! as? Data{
do {
let jsonResult:NSDictionary = try JSONSerialization.jsonObject(with: responsedata, options: []) as! NSDictionary
print("Get The Result \(jsonResult)")
if error != nil {
// print("error=\(error)")
}
if let str = jsonResult["success"] as? NSNull {
print("error=\(str)")
}
else {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Response string : \(responseString)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}) .resume()
}catch {
// print("Error -> \(error)")
}
hope this might help you out.
Creating JSON parameters to send it as a post body:
Function:
//MARK:- Create JSON String
func createJSONParameterString(postBody:AnyObject) -> String {
if let objectData = try? JSONSerialization.data(withJSONObject: postBody, options: JSONSerialization.WritingOptions(rawValue: 0)) {
let objectString = String(data: objectData, encoding: .utf8)
return objectString ?? ""
}
return ""
}
Usage:
var postBody = [AnyHashable:Any]()
postBody["device_id"] = "device_ID"
let parameters = createJSONParameterString(postBody: postBody as AnyObject)
print(parameters)
i have solved similar problem using Alamofire and SwiftyJson as follow
let call your object (data )
let json = JSON(data)
let Params :Dictionary = json.dictionaryObject!
and in Alamofire request
Alamofire.request(url, method: .post, parameters: Params , encoding: JSONEncoding.prettyPrinted, headers: nil)
//.validate(statusCode: 200..<300)
.responseJSON { response in
switch response.result
{
case .failure(let error):
case .success(let value):
}
it need to replace this "{ }" with "[ ]"
and alamofire and swift json handle that issue
ex:
[
{
"firstName" : " " ,
"lastName" : " "
},
{
"firstName" : " " ,
"lastName" : " "
}
]
change it to
[
[
"firstName" : " " ,
"lastName" : " "
],
[
"firstName" : " " ,
"lastName" : " "
]
]

The data couldn’t be read because it isn’t in the correct format - HTTP network

code
let session = URLSession.shared
// prepare json data
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
let proceedURL = NSURL(string:"https://mysitename.herokuapp.com/api/users/isUser")
//let proceedURL = NSURL(string:"https://google.com")
let request = NSMutableURLRequest(url: proceedURL! as URL)
//HTTP Headers
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/www.inception.v1", forHTTPHeaderField: "Accept")
request.addValue("Authorization", forHTTPHeaderField: "Basic aW5jZXB0aW9uQGZ1cmRvOmljM=")
request.httpMethod = "POST"
//request.httpBody = jsonData
// insert json data to the request
request.httpBody = jsonData
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
// Print out response string
let responseString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString!)")
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: AnyObject] {
print(json)
// handle json...
}
} catch let error {
print("error : " + error.localizedDescription)
}
})
task.resume()
error :
The data couldn’t be read because it isn’t in the correct format.
I am beginner in iphone app development, help me on it and give better suggestion for make network connection (like in android i am using Volley library )
Actual Response is :
{
"status": 1,
"http_status_code": 200,
"data": {
"email": "test_mobile#mysite.com",
"phone": "8090909000"
}
}
i am using same on Android and test in postmen.
// Print out response string
let responseString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
for upper code response is nothing
Using Alamofire.
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
Alamofire.request(.POST, "https://mysitename.herokuapp.com/api/users/isUser" , parameters: json, encoding: .JSON).responseJSON {
Response in
switch Response.result {
case .Success(let _data):
let JsonData = JSON(_data)
print("JsonData : \(JsonData)")
//handle json
case .Failure(let _error):
print(_error)
let AlertBox = UIAlertController(title: "Connection Failed", message: "No Connection", preferredStyle: .Alert)
let ActionBox = UIAlertAction(title: "Ok" , style: .Default, handler: { _ in})
AlertBox.addAction(ActionBox)
self.presentViewController(AlertBox, animated: true, completion: nil)
}
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "http://httpbin.org/post")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()

Working with Alamofire

Working with Alamofire, getting:
Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error
Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character
2." error
Here is my code in NetworkClass:
class func requestPOSTURL(_ strURL : String, params :[String:String], success:#escaping (JSON) -> Void, failure:#escaping (Error) -> Void){
Alamofire.request(strURL, method: .post, parameters: params, encoding: JSONEncoding.default).responseJSON { (responseObject) -> Void in
print(responseObject)
if responseObject.result.isSuccess {
let resJson = JSON(responseObject.result.value!)
success(resJson)
}
if responseObject.result.isFailure {
let error : Error = responseObject.result.error!
failure(error)
}
}
}
and request call:
let strURL = "myurl"
let parameters : [String: String] =
[
"user_name":"SNSH" as String,
"password":"SNOSH" as String,
"device_id":"0D4F5322-81C0-0000-9210-70DA0C6BC04C" as String,
]
if let json = try? JSONSerialization.data(withJSONObject: parameters, options: []) {
// here `json` is your JSON data, an array containing the String
// if you need a JSON string instead of data, then do this:
if let content = String(data: json, encoding: String.Encoding.utf8) {
// here `content` is the JSON data decoded as a String
print(content)
print(parameters)
NetworkClass.requestPOSTURL(strURL, params: parameters, success: {
(JSONResponse) -> Void in
print(JSONResponse)
}) {
(error) -> Void in
print(error)
}
}
}
I need to send String in parameters.
let urlAsString1 : String = API
let urlStr : NSString = urlAsString1.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
let params:NSMutableDictionary? = [
"user_name":"SNSH" as String,
"password":"SNOSH" as String,
"device_id":"0D4F5322-81C0-0000-9210-70DA0C6BC04C" as String,
];
let ulr = NSURL(string:urlStr as String)
let request = NSMutableURLRequest(URL: ulr!)
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let data = try! NSJSONSerialization.dataWithJSONObject(params!, options: NSJSONWritingOptions.PrettyPrinted)
let json = NSString(data: data, encoding: NSUTF8StringEncoding)
if let json = json {
print(json)
}
request.HTTPBody = json!.dataUsingEncoding(NSUTF8StringEncoding);
Alamofire.request(request)
.responseJSON { response in
// do whatever you want here
switch (response.result) {
case .Success(let JSON):
print("JSON: \(JSON)")
let responseString = JSON as! NSDictionary
print(responseString)
break;
case .Failure:
break
}
}
}

AFNetworking pass data with "x-www-form-urlencoded" type

In post man if I pass the data with x-www-form-urlencoded it will give me success response in it, but same thing I try with afnetworking then it does not work for me.
I know this question has already answer but some were very old and method which is used in was deprecated and some I tried but not worked for me
My code is as below
static func calledApi(withApiName strName:String,withParameter dictData:NSDictionary,withSuccessBlock objSuccess:successBlock,withFailureBlock objFailure:failureBlock){
strBaseUrl = strBaseUrl.stringByAppendingString(strName)
let manager = AFHTTPSessionManager(sessionConfiguration: NSURLSessionConfiguration.defaultSessionConfiguration())
manager.requestSerializer.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
// manager.requestSerializer.setQueryStringSerializationWithBlock { (request, id,error) -> String in
// let jsonData = try! NSJSONSerialization.dataWithJSONObject(dictData, options: .PrettyPrinted)
// let myString = String(data: jsonData, encoding: NSUTF8StringEncoding)
// return myString!
// }
// manager.requestSerializer = AFHTTPRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.POST(strBaseUrl, parameters: dictData, progress: { (progress) in
}, success: { (session, responceObj) in
let datastring : String = String(data: (responceObj as! NSData), encoding: NSUTF8StringEncoding)!
print(datastring)
var dictData = NSDictionary()
do {
dictData = try NSJSONSerialization.JSONObjectWithData((responceObj as! NSData), options: []) as! [String:AnyObject]
} catch let error as NSError {
print(error)
return
}
if Int(dictData.valueForKey("code") as! String) == 1
{
objSuccess(dictData)
}
else
{
objFailure(nil, dictData.valueForKey("message") as! String)
}
}) { (session, error) in
print(error)
objFailure(error,nil)
}
}

Resources