I've been trying to get a JSON String to a Dictionary Value, and I can't get it to work, I'm getting an empty value. Before I tried to pull the data I checked that I got the all JSON, so obviously I'm doing something wrong here
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options:
NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
var items = [[String:String]()]
var item:AnyObject
var authorDictionary:AnyObject
for var i = 0; i < jsonResult["item"]?.count; i++ {
items.append([String:String]())
item = (jsonResult["items"] as? [[NSObject:AnyObject]])!
items[i]["content"] = item["content"] as? String
items[i]["title"] = item["title"] as? String
items[i]["publishedDate"] = item["published"] as? String
authorDictionary = item["author"] as! NSDictionary
items[i]["author"] = item["displayName"] as? String
}
println(items)
That's what I got as a result:
[[:]]
I am new to JSON, can someone explain me what I should do and what I did wrong?
You can iterate directly over jsonResult["items"] if it has the right type declared (array of dictionaries).
Then inside the loop you have to create a new dictionary each time, fill this dictionary with the data you grab from the JSON response, then you append the new dictionary to your items array of dictionaries:
var items = [[String:String]]()
for item in jsonResult["items"] as! [[String:AnyObject]] {
var newDict = [String:String]()
newDict["content"] = item["content"] as? String
newDict["title"] = item["title"] as? String
newDict["publishedDate"] = item["published"] as? String
newDict["author"] = item["displayName"] as? String
items.append(newDict)
}
As for authorDictionary, since it's a simple dictionary and not an array, if you assign it a value in the loop, it will be overwritten each time and all you'll have in the end is the author from the last object.
Check this out
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
var items = [[String:String]()]
var item:AnyObject
var authorDictionary:AnyObject
for var i = 0; i < jsonResult["items"]!.count; i++
{
items.append([String:String]())
item = (jsonResult["items"] as! [NSDictionary])[i]
items[i]["content"] = item["content"] as! NSString as String
items[i]["title"] = item["title"] as! NSString as String
items[i]["publishedDate"] = item["published"] as! NSString as String
authorDictionary = item["author"] as! NSDictionary
items[i]["author"] = authorDictionary["displayName"] as! NSString as String
}
println(items)
Related
I have made a struct that is helping me fetching info from a twitter json. The json has values such as text, which I am able to fetch without a problem, but it also has a dictionary names user and it has the string screen_name inside it.
How can I access that string?
Here is how I access the text string and how I fetch the user dictionary:
func parseTwitterJSON(_ data:Data) {
var jsonResult = NSArray()
do{
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let twitterLocations = NSMutableArray()
for i in 0 ..< jsonResult.count{
jsonElement = jsonResult[i] as! NSDictionary
let twitterLocation = twitterLocationModel()
//the following insures none of the JsonElement values are nil through optional binding
if let lang = jsonElement["lang"] as? String,
let text = jsonElement["text"] as? String,
let user = jsonElement["user"] as? NSDictionary
{
twitterLocation.lang = lang
twitterLocation.text = text
twitterLocation.user = user
}
twitterLocations.add(twitterLocation)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.twitterDownloaded(items: twitterLocations)
})
}
To access the value of a key from a dictionary you would use
let myDictName : [String:String] = ["keyName" : "value"]
let value = myDictName["keyName"]
//value will be equal to "value"
Since you have the element user as an dictionary, you can just say
let userName = user["screen_name"]
I have a json like this:
{"page":1,"totalPage":1,"listContent":[{"bizID":3,"bizName":"SHELL KEMANGGISAN","bizImage":"http//:www.goog#gmail.com","address":"JL KEMANGGISAN UTAMA, JAKARTA, 11480, INDONESIA","ratingAvg":1.0,"distance":14003691},{"bizID":4,"bizName":"SHELL DAAN MOGOT","bizImage":"http//:www.goog#gmail.com","address":"JL DAAN MOGOT KM 11, JAKARTA, 11710","ratingAvg":3.0,"distance":14004238}]}
I try to catch the result like this but error:
do {
let jsonArr = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! NSArray
print("jsonArr:\(jsonArr)")
for json in jsonArr {
if let results = json["listContent"] as? NSArray {
for result in results {
let person = Bizz()
person.bizID = result["bizID"] as! String
person.bizName = result["bizName"] as! String
person.bizImage = result["bizImage"] as! String
person.address = result["address"] as! String
person.ratingAvg = result["ratingAvg"] as! String
self.businessBizz.append(person)
}
}
}
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
} catch {
print("Failed to get Content List: \(error)")
}
the error is:
Could not cast value of type '__NSCFString' (0x10756f2c8) to 'NSArray' (0x10756fb88).
the error at this line:
let jsonArr = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! NSArray
how to repair it? and get listcontent value.
Your JSON is [String: AnyObject] means Dictionary not an array..
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
if let results = json["listContent"] as? [[String: AnyObject]] {
for result in results {
let person = Bizz()
person.bizID = result["bizID"] as! Int
person.bizName = result["bizName"] as! String
person.bizImage = result["bizImage"] as! String
person.address = result["address"] as! String
person.ratingAvg = result["ratingAvg"] as! Float
self.businessBizz.append(person)
}
}
You should also convert result["ratingAvg"] and result["bizID"] to Int and Float respectively because they are converted to NSNumber upon being parsed.
You can download the playground from here and test that out yourself.
Here goes my code.
func connectionDidFinishLoading(connection: NSURLConnection){
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
if jsonResult.count>0 && jsonResult["results"]!.count>0 {
var result: NSArray = jsonResult["results"] as! NSArray
println("\(result)")
var dict = NSDictionary()
var myDict = NSDictionary()
for dict in result {
let googleGeo = dict["geometry"] as! NSDictionary
let googleLoc = googleGeo["location"] as! NSDictionary
let latitude = googleLoc["lat"] as! Float
let longitude = googleLoc["lng"] as! Float
let googleicon = dict.valueForKey("icon") as? NSString
let googlename = dict["name"] as? NSString
let googlevicinity = dict["vicinity"] as? NSString
myDict.setValue(latitude, forKey: "lat"
}
}
}
After parsing from Google Places API, i received longitude, latitude, name, vicinity, icon. Now i want to append these value to myDctionary so that i can pass the value to an array and to the next view controller.
Please someone let me know to to do it ?
My friend, you should try this.
Let the dictionary know exactly what type of key/value pairs you want it to hold. You want to use a "String" as the key and since your values have different datatypes you want to use "AnyObject" as the value.
UPDATE For Swift 2 you would use String:AnyObject but for Swift3 you would use String:Any. I've updated the code to show the Swift 3 version instead.
//this says your dictionary will accept key value pairs as String/Any
var myDict = [String:Any]()
You use Any because you have so many different datatypes
//Your values have are being cast as NSDictionary, Float, and NSStrings. All different datatypes
let googleGeo = dict["geometry"] as? NSDictionary
let googleLoc = googleGeo["location"] as? NSDictionary
let latitude = googleLoc["lat"] as? Float
let longitude = googleLoc["lng"] as? Float
let googleicon = dict.valueForKey("icon") as? NSString
let googlename = dict["name"] as? NSString
let googlevicinity = dict["vicinity"] as? NSString
Now you use the method .updateValue(value: Value, forKey: Hashable) to set your keys and values
//update the dictionary with the new values with value-type Any and key-type String
myDict.updateValue(googleGeo, forKey: "geometry")
myDict.updateValue(googleLoc, forKey: "location")
myDict.updateValue(latitude, forKey: "lat")
myDict.updateValue(longitude, forKey: "lng")
myDict.updateValue(googleicon, forKey: "icon")
myDict.updateValue(googlename, forKey: "name")
myDict.updateValue(googlevicinity, forKey: "vicinity")
myDict should now have have all these key/value pairs and you do what you want with them by using the key to extract the value. Btw I only used those key names because for your post it seemed that's the convention you was using. You can name the keys whatever you want. But whatever you name them they have to be the same name you use to extract the value.
Hope this helps!
I've downloaded the data below which is in Json format.
{"name":"Shropshire Outage","nc_lead":"John Smith","dma":"11/111","username":"vwaghx1","status":"REOPENED","sapOrder":"12341245","ccsText":"123","nbPropAtRisk":12,"logs":[{"dateTime":"2016-04-07 20:02:42","valveStatusChangeDateTime":"2016-04-07 20:02:00","user":"vwaghx1","uid":null,"task":"CUSTPOORSUPPLIES","id_log":1489},{"dateTime":"2016-04-07 20:03:35","valveStatusChangeDateTime":"2016-04-07 20:02:00","user":"vwaghx1","uid":1238768765,"task":"PRESSURELOGGER","id_log":1490},{"dateTime":"2016-04-07 20:04:36","valveStatusChangeDateTime":"2016-04-07 20:02:00","user":"vwaghx1","uid":7692466478,"task":"CUSTSUPPLIESRESTOREDSOME","id_log":1491}],"id_event":601,"region":"Shropshire","trigger":"No Supply Call”,”valveOps":[{"dateTime":"2016-04-07 20:06:12","user":"vwaghx1","uid":7866756788,"x":678666,"y":723325,"description”:”Burst main downstream valve","id_valve_op":523},{"dateTime":"2016-04-07 20:05:31","user":"vwaghx1","uid":5674456470,"x":344534,"y":723433,"description":"Valve to separate both rezones","id_valve_op":522},{"dateTime":"2016-04-14 12:32:00","user":"vwaghx1","uid":1234512345,"x":123123,"y":123123,"description":"test","id_valve_op":541}],"images":[{"name":"After improvement.jpg","dateTimeCreated":"2016-04-08 14:10:30","contentType":"image/jpeg","caption":null,"uuid":null,"fileExtension":"jpeg","id_image":661},...]}
However, when I try to parse it using the code below, I can only access the string values such as "name","nc_lead", "region" etc.
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments) as? Array<Dictionary<String, AnyObject>> {
for item in json {
if let dict = item as? Dictionary<String, AnyObject> {
if let nameStr = dict["name"] as? String {
incidentList.valueStr = nameStr
}
if let codeStr = dict["dma"] as? String {
incidentList.valueStr = codeStr
}
if let region = dict[“region”] as? String {
incidentList.valueStr = region
}
if let ncLead = dict[“nc_lead”] as? String {
incidentList.valueStr = ncLead
}
I need to access the group values like "logs", "images" and "valveOps", which have their own string values in arrays.
How can I change my code so that I can access the strings as I am now and also load the groups into arrays?
You can try like this way, declare 3 array first.
var logArr: [[String: AnyObject]] = [[String: AnyObject]]()
var imageArr: [[String: AnyObject]] = [[String: AnyObject]]()
var valveArr: [[String: AnyObject]] = [[String: AnyObject]]()
Now use this array where you are getting response
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments) as? Array<Dictionary<String, AnyObject>> {
for item in json {
if let dict = item as? Dictionary<String, AnyObject> {
if let nameStr = dict["name"] as? String {
incidentList.valueStr = nameStr
}
if let codeStr = dict["dma"] as? String {
incidentList.valueStr = codeStr
}
if let region = dict["region"] as? String {
incidentList.valueStr = region
}
if let ncLead = dict["nc_lead"] as? String {
incidentList.valueStr = ncLead
}
if let logs = dict["logs"] as? [[String: AnyObject]] {
self.logArr = logs
}
if let valveOps = dict["valveOps"] as? [[String: AnyObject]] {
self.valveArr = valveOps
}
if let images = dict["images"] as? [[String: AnyObject]] {
self.imageArr = images
}
I have a JSON String like this:
let stringArray = "[{\"url\":\"www.abc.com\",\"name\":\"benson\",\"age\":25},{\"url\":\"www.abc.com\",\"name\":\"tommy\",\"age\":23}]"
How can I remove one item(for example,tommy) in this string?
I tried to cast it to [[NSObject: AnyObject]] but always failed.
if let dictArray = stringArray as? [[NSObject: AnyObject]] {
} else {
println("failed") // print failed.
}
How can I get the result like this:
[{\"url\":\"www.abc.com\",\"name\":\"benson\",\"age\":25}]
Convert your string to array because its JSON String
var stringArray = "[{\"url\":\"www.abc.com\",\"name\":\"benson\",\"age\":25},{\"url\":\"www.abc.com\",\"name\":\"tommy\",\"age\":23}]"
var data : NSData = stringArray.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
var error: NSError?
var array = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as Array<AnyObject>
println(array)
Output :
[{
age = 25;
name = benson;
url = "www.abc.com";
}, {
age = 23;
name = tommy;
url = "www.abc.com";
}]
Now perform delete operation
array.removeAtIndex(1)
println(array)
Output :
[{
age = 25;
name = benson;
url = "www.abc.com";
}]
First convert your json string to swift array or dictionary;
let stringArray:String = "[{\"url\":\"www.abc.com\",\"name\":\"benson\",\"age\":25},{\"url\":\"www.abc.com\",\"name\":\"tommy\",\"age\":23}]"
let data:NSData = stringArray.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!;
let dict:NSArray = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as! NSArray;
NSLog("dict \(dict)");
Maybe you can cast the original jsons string to the dictionary then pick up the keys what your needs. as the sample code like :
if let json = NSJSONSerialization.JSONObjectWithData("your string to NSDATA",options:NSJSONReadingOptions.AllowFragments,$error){
// checks the son type and make sure the operation perform to the NSDictionary
var d = json as! NSDictionary;
// Picks the the values your want from d
}