Parsing swift arrays into valid json - ios

So the issue I am facing is that i have two arrays in an ios app which i need to store in a remote mySQL database, which i would like to accomplish using php and json. I haven't, however, despite several days of work, managed to get the arrays in the ios app converted into json code which doesn't crash the app. The arrays are populated by a qr code reader and input field, and there is always an equal amount of items in each array. Currently the code below generates the following json:
json string = {"b":"[\n\n]","p":"[\n\n]"}
No matter what changes i do, the app seems to crash with the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write', or alternatively it says 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.} with some of my other experiments (like the version currently below)
var productArray = [String]()
var amountArray = [String]()
func addTapped(sender: UIBarButtonItem) {
print("Running add func")
do {
var test1 = ""
var test2 = ""
//Convert to Data
let jsonData1 = try! JSONSerialization.data(withJSONObject: amountArray, options: JSONSerialization.WritingOptions.prettyPrinted)
let jsonData2 = try! JSONSerialization.data(withJSONObject: productArray, options: JSONSerialization.WritingOptions.prettyPrinted)
//Convert back to string. Usually only do this for debugging
if let JSONString1 = String(data: jsonData1, encoding: String.Encoding.utf8) {
print(JSONString1)
test1 = JSONString1
}
if let JSONString2 = String(data: jsonData2, encoding: String.Encoding.utf8) {
print(JSONString2)
test2 = JSONString2
}
//In production, you usually want to try and cast as the root data structure. Here we are casting as a dictionary. If the root object is an array cast as [AnyObject].
var json1 = try JSONSerialization.jsonObject(with: jsonData1, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: AnyObject]
var json2 = try JSONSerialization.jsonObject(with: jsonData2, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: AnyObject]
let dict = ["json1": test1, "json2": test2] as [String: Any]
print("All JSON should print below")
print(dict)
if let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted) {
let url = NSURL(string: "http://www.server.com/receiver")!
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request as URLRequest){ data,response,error in
if error != nil{
print(error?.localizedDescription)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue:String = parseJSON["success"] as! String;
print("result: \(resultValue)")
print(parseJSON)
}
} catch let error as NSError {
print(error)
}
}
task.resume()
}
} catch {
print("Oops")
}
}

I think the best solution is using SwiftyJSON
Whit that, if you have a String you can use var json = JSON.parse(yourString)

Related

Is WS Websocket able to send or receive json object in Swift?

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (_NSInlineData)'
let data = /* type of data */
let dic : NSDictionary = ["ID" : "UserName", "Data" : data]
let jsonData = try? JSONSerialization.data(withJSONObject: dic, options: [])
self!.socket.write(data: jsonData!)
Create a string from your data and you can send that.
func jsonToString(json: AnyObject) -> String{
do {
let data1 = try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted)
let convertedString = String(data: data1, encoding: String.Encoding.utf8)
return convertedString!
} catch let myJSONError {
print(myJSONError)
return ""
}
}
You can use it:
let messageString = jsonToString(json: jsonData as AnyObject)
socket.write(string: messageString)
It's impossible because socket writes string or buffer can't accept an object. I can send it when I convert data to base64 and convert jsonData to String.
But I want to send it as Data.
let data = /* type of data */
let dataAsString = data!.base64EncodedString()
let dic : NSDictionary = ["ID" : "UserName", "Data" : dataAsString]
let jsonData = try? JSONSerialization.data(withJSONObject: dic, options: [])
let jsonString = String(data: jsonData!, encoding: .utf8)
self!.socket.write(string: jsonString!)

How to convert rawString to JSON Array?

I am trying to convert jsonString.rawString() to JSON object, but it returns nil.
let jsonData = newsfeedData.rawString()?.data(using: .utf8)
let object = try? JSONSerialization.jsonObject(with: jsonData!, options: .mutableContainers)
print(object) //it returns nil
This is the jsonString:
Printing description of newsfeedData.rawString:
"Data:[{\"UserID\":1,\"post\":[{\"PostId\":1,\"UserId\":1,\"UserName\":\"party Patel\",\"ImagePath\":\"/Files/User/user_20180606_040913967_Hydrangeas.jpg\",\"FileId\":2108,\"FileName\":\"Business Category.png\",\"Email\":\"parth.patel#shaligraminfotech.com\",\"Location\":\"Ahmedabad\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Photo/fd1c7fcf-e1d0-4ffe-afb4-42bb3fea4fa4.PNG\",\"UserRole\":\"Business\",\"BusinessName\":\"Shaligram infotech\",\"PostType\":false,\"Type\":\"Photo\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":4,\"CommentCount\":4,\"ViewCount\":3},{\"PostId\":3,\"UserId\":1,\"UserName\":\"party Patel\",\"ImagePath\":\"/Files/User/user_20180606_040913967_Hydrangeas.jpg\",\"FileId\":2110,\"FileName\":\"DiscovrUS.mov\",\"Email\":\"parth.patel#shaligraminfotech.com\",\"Location\":\"Ahmedabad\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Video/ab48c228-d7b5-4dff-af56-31a0ac159a35.MOV\",\"UserRole\":\"Business\",\"BusinessName\":\"Shaligram infotech\",\"PostType\":true,\"Type\":\"Video\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":1,\"CommentCount\":0,\"ViewCount\":1}]},{\"UserID\":2,\"post\":[{\"PostId\":2,\"UserId\":2,\"UserName\":\"tejas Padia\",\"ImagePath\":\"/Files/User/user_20180606_062946997_Tulips.jpg\",\"FileId\":2109,\"FileName\":\"DiscovrUS.mov\",\"Email\":\"tejaspadia#gmail.com\",\"Location\":\"India\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Video/2d892eaf-b6dc-433d-985b-2a4588ffd307.MOV\",\"UserRole\":\"Individual\",\"BusinessName\":\"\",\"PostType\":true,\"Type\":\"Video\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":3,\"CommentCount\":0,\"ViewCount\":0}]}]"
Make sure json format your value invalid format
just try replace Data: to empty string "" , Your code it's working
do{
var json = "Data:[{\"UserID\":1,\"post\":[{\"PostId\":1,\"UserId\":1,\"UserName\":\"party Patel\",\"ImagePath\":\"/Files/User/user_20180606_040913967_Hydrangeas.jpg\",\"FileId\":2108,\"FileName\":\"Business Category.png\",\"Email\":\"parth.patel#shaligraminfotech.com\",\"Location\":\"Ahmedabad\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Photo/fd1c7fcf-e1d0-4ffe-afb4-42bb3fea4fa4.PNG\",\"UserRole\":\"Business\",\"BusinessName\":\"Shaligram infotech\",\"PostType\":false,\"Type\":\"Photo\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":4,\"CommentCount\":4,\"ViewCount\":3},{\"PostId\":3,\"UserId\":1,\"UserName\":\"party Patel\",\"ImagePath\":\"/Files/User/user_20180606_040913967_Hydrangeas.jpg\",\"FileId\":2110,\"FileName\":\"DiscovrUS.mov\",\"Email\":\"parth.patel#shaligraminfotech.com\",\"Location\":\"Ahmedabad\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Video/ab48c228-d7b5-4dff-af56-31a0ac159a35.MOV\",\"UserRole\":\"Business\",\"BusinessName\":\"Shaligram infotech\",\"PostType\":true,\"Type\":\"Video\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":1,\"CommentCount\":0,\"ViewCount\":1}]},{\"UserID\":2,\"post\":[{\"PostId\":2,\"UserId\":2,\"UserName\":\"tejas Padia\",\"ImagePath\":\"/Files/User/user_20180606_062946997_Tulips.jpg\",\"FileId\":2109,\"FileName\":\"DiscovrUS.mov\",\"Email\":\"tejaspadia#gmail.com\",\"Location\":\"India\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Video/2d892eaf-b6dc-433d-985b-2a4588ffd307.MOV\",\"UserRole\":\"Individual\",\"BusinessName\":\"\",\"PostType\":true,\"Type\":\"Video\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":3,\"CommentCount\":0,\"ViewCount\":0}]}]"
json = json.replacingOccurrences(of: "Data:", with: "")
if let data = json.data(using: .utf8) {
do {
let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]]
print(jsonResult)
} catch {
print(error.localizedDescription)
}
}

Swift How to update (modify, Delete, Add) entries of JSON

Hello i need some help here, I'm making an IOS app that gets data from a JSON API and then showing the results on a Table , when i tap on a result from the table it goes to a second view controller where i'm showing the details. What I want to do is to update the info I'm showing on the details, delete entries from the JSON by deleting them from the table itself, and add a new entry to be saved on the JSON.
This is the JSON structure:
{
_id: "57eec6c9dfc2fb03005c0dd0",
ssid: "nonummy",
password: "accumsan",
lat: 29.39293,
lon: 115.71771,
summary: "curae nulla dapibus dolor vel est donec odio justo sollicitudin ut",
__v: 0,
likes: 1,
unlikes: 0,
bssid: "EF:CD:AB:56:34:12"
},
I want to be able to update the SSID, Password and Summary.
this is the code I'm using to get the Result from the JSON and is working good
Code:
let url = URL(string:"https://fierce-peak-97303.herokuapp.com/api/wifi")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error)
}else {
if let urlContent = data {
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers)
//print(jsonResult))
for item in(jsonResult as? NSArray)! {
let ssid = (item as? NSDictionary)?["ssid"] as? NSString
//print(ssid)
}
self.tableData = jsonResult as! NSArray
DispatchQueue.main.sync(execute: {
self.table.reloadData()
})
}catch {
print("No Json Result Was Found")
}
}
}
}
task.resume()
For example if I click on one line of the table I want to be able to update password.
I managed to do it like this : all formatted for swift 3
//declare parameter as a dictionary which contains string as key and value combination.
let parameters = ["ssid": newSSID.text!,"password": newPass.text!,"lat": newLat.text!,"lon": newLon.text!,"summary": newSum.text!] as Dictionary<String, String>
//create the url with NSURL
let url = URL(string: "https://fierce-peak-97303.herokuapp.com/api/wifi")
//create the session object
let session = URLSession.shared
//now create the NSMutableRequest object using the url object
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
var err : NSError?
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
}catch{
print("error")
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
print("Response: \(response)")
let strData = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Body: \(strData)")
var err: NSError?
do {
var json = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as? NSDictionary
}catch{
print("JSON error")
}
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(err != nil) {
print(err!.localizedDescription)
let jsonStr = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Error could not parse JSON: '\(jsonStr)'")
}
else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as? NSDictionary
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("Success: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Error could not parse JSON: \(jsonStr)")
}
}catch{
print("JSON error")
}
}
You can get the contents of the json file as whatever data structure you want, then overwrite the values that you want to change and finally overwrite the original file when you want to save your changes:
So you're already getting the JSON as an array:
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers)
let array = (jsonResult as? NSArray)!
So now you can just change the values in array, when you're done changing everything you want then you can overwrite the json file: (swift 3.0)
var jsonData: NSData!
// serialize json dataa
do
{
jsonData = try JSONSerialization.dataWithJSONObject(array, options: NSJSONWritingOptions())
let jsonString = String(data: jsonData as Data, encoding: String.Encoding.utf8)
print(jsonString)
}
catch let error as NSError
{
print("Array to JSON conversion failed: \(error.localizedDescription)")
}
// overwrite the contents of the original file.
do
{
let file = try FileHandle(forWritingToURL: url!)
file.writeData(jsonData)
print("JSON data was written to the file successfully!")
}
catch let error as NSError
{
print("Couldn't write to file: \(error.localizedDescription)")
}
I'm not sure exactly how writing to a server works, but since it's a URL i think it should act the same way.
Update:
So your original array is:
let array = (jsonResult as? NSArray)!
You can cast it to an array of dictionaries like so
var dictionaries : [[String: NSObject]] = array as? [[String: NSObject]]
and you get ssid by doing:
int i = 0;
for (dictionary in dictionaries)
{
let ssid = dictionary["ssid"]
let newSSID = ssid + "something I want to edit my values with"
// now we have our new value, so we update the array
dictionaries[i]["ssid"] = newSSID
i += 1
}
now after this we just overwrite the original file with the new dictionaries object, which I wrote out above.

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.

My swift app fail to convert NSData to Json

I was trying to convert NSData to Json by doing this:
let jdata = getJSON("https://api.myjson.com/bins/16j2i")
do {
let json = try NSJSONSerialization.JSONObjectWithData(jdata, options: []) as! [String: AnyObject]
print(json)
} catch {
print("\(error)")
}
This is the getJSON method
func getJSON(url:String) -> NSData {
return NSData(contentsOfURL: NSURL(string: url)!)!
}
A error says that could not cast value of type '_NSCFArray' to 'NSDictionary'. Any ideas? Please
The root element of your JSON is array not dictionary (Your format looks something like [{...},{...}] ). For fixing this error you need to change the parsing code to:
let json = try NSJSONSerialization.JSONObjectWithData(jdata, options: []) as! [[String: AnyObject]]
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
let convert_array = responseString?.description
// Convert server json response to NSDictionary
do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data!, options: []) as? NSArray {
print(convertedJsonIntoDict)
}
let data = text.data(using: String.Encoding.utf8)
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any]
Working Fine for Swift 3.1 & Swift 4

Resources