I'm trying to parse the JSON response below using the following code but can't seem to get it to work, how would I do this? Im trying to get "user_guid" and all the "entity_guid" in images.
SWIFT
do {
var entity_guid : Int = 0
var user_guid : Int = 0
let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
// Parse JSON data
let jsonP = jsonResult?["result"] as! [AnyObject]
for jsonL in jsonP {
user_guid = jsonL["user_guid"] as! Int
entity_guid = jsonL["entity_guid"] as! Int
}
} catch {
}
JSON
{
"status":0,
"result":{
"user_guid":139219,
"images":[
{
"entity_guid":572356
},
{
"entity_guid":572354
},
{
"entity_guid":572352
}
]
}
}
Try below code:
do {
var entity_guid : Int = 0
var user_guid : Int = 0
let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:Any]
// Parse JSON data
let jsonP = jsonResult?["result"] as! [String:Any]
user_guid = jsonP["user_guid"] as! Int
let images = jsonP["images"] as! [[String:Int]]
for jsonL in images {
entity_guid = jsonL["entity_guid"]!
}
} catch {
print(error.localizedDescription)
}
Replace below code and try to check. You must use Swift datatypes wherever possible.
do {
var entity_guid : Int = 0
var user_guid : Int = 0
let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any]
guard let jsonP = jsonResult["result"] as [String: Any] else {
return
}
user_guid = jsonP["user_guid"] as! Int
if let jsonArr = jsonP["images"] as? [String] {
for image in jsonArr {
entity_guid = image["entity_guid"] as! Int
}
}
Related
In the api am getting global array but in this I am unable to get the children names as separate array only the last loaded array name has been getting in the array how to get the all children names in the array please help me how to get all the names in it and here is my code already tried
var detailsArray = NSArray()
var globalArray = NSMutableArray()
let url = "http://www.json-generator.com/api/json/get/cwqUAMjKGa?indent=2"
func downloadJsonWithURL() {
let url = NSURL(string: self.url)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
{
self.detailsArray = (jsonObj?.value(forKey: "data") as? [[String: AnyObject]])! as NSArray
print(self.detailsArray)
for item in self.detailsArray
{
let majorDic = NSMutableDictionary()
let detailDict = item as! NSDictionary
print(detailDict["name"]!)
majorDic .setValue(detailDict["name"]!, forKey: "name")
print(detailDict["children"]!)
if !(detailDict["children"]! is NSNull)
{
let children = detailDict["children"]! as! NSArray
let childrenstring = NSMutableString()
if children.count > 0 {
for item in children{
let chilDic = item as! NSDictionary
print(chilDic["name"]!)
print(chilDic["products"]!)
majorDic.setValue(chilDic["name"]!, forKey: "Childernname")
let products = chilDic["products"]! as! NSArray
if products.count > 0
{
for item in products
{
var sr = String()
sr = (item as AnyObject) .value(forKey: "name") as! String
childrenstring.append(sr)
childrenstring.append("*")
}
majorDic.setValue(childrenstring, forKey: "Childernproducts")
}
else
{
print("products.count\(products.count)")
majorDic.setValue("NO DATA", forKey: "Childernproducts")
}
}
}
else
{
print("childernw.count\(children.count)")
majorDic.setValue("NO DATA", forKey: "Childernname")
}
}
else
{
majorDic.setValue("NO DATA", forKey: "Childernname")
majorDic.setValue("NO DATA", forKey: "Childernproducts")
}
self.globalArray.add(majorDic)
}
print("TOTAL ASSECTS\(self.globalArray)")
OperationQueue.main.addOperation({
self.tableView.reloadData()
print(self.globalArray)
print(self.detailsArray)
})
}
}).resume()
}
Try this:
var detailsArray = [DataList]()
func downloadJsonWithURL() {
let url = NSURL(string: "http://www.json-generator.com/api/json/get/cwqUAMjKGa?indent=2")
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
{
let objArr = (jsonObj?["data"] as? [[String: AnyObject]])! as NSArray
for obj in objArr {
self.detailsArray.append(DataList(json: obj as! [String : AnyObject]))
}
print(self.detailsArray)
}
}).resume()
}
Model Class
class DataList: NSObject {
var count: Int
var category_id: Int
var childern:[Children]
var name:String
init (json: [String: AnyObject]){
if let childrenList = json["children"] as? [[String: AnyObject]] {
var result = [Children]()
for obj in childrenList {
result.append(Children(json: obj))
}
self.childern = result
} else {
self.childern = [Children]()
}
if let count = json["count"] as? Int { self.count = count }
else { self.count = 0 }
if let category_id = json["category_id"] as? Int { self.category_id = category_id }
else { self.category_id = 0 }
if let name = json["name"] as? String { self.name = name }
else { self.name = "" }
}
}
class Children:NSObject{
var count:Int
var category_id:Int
var products:[Products]
var name:String
init (json: [String: AnyObject]){
if let productList = json["products"] as? [[String: AnyObject]] {
var result = [Products]()
for obj in productList {
result.append(Products(json: obj))
}
self.products = result
} else {
self.products = [Products]()
}
if let count = json["count"] as? Int { self.count = count }
else { self.count = 0 }
if let category_id = json["category_id"] as? Int { self.category_id = category_id }
else { self.category_id = 0 }
if let name = json["name"] as? String { self.name = name }
else { self.name = "" }
}
}
class Products:NSObject{
var product_id:Int
var name:String
init (json: [String: AnyObject]){
if let product_id = json["product_id"] as? Int { self.product_id = product_id }
else { self.product_id = 0 }
if let name = json["name"] as? String { self.name = name }
else { self.name = "" }
}
}
NOTE: Please check your data type while parsing
I too had the same problem. Instead of using for loop try using flatMap() and then extract the value using value(forKey: " ") function
let productNames = productValues.flatMap() {$0.value}
let names = (productNames as AnyObject).value(forKey: "name")
It had worked for me for my json. My Json was similar to yours.
I got separate values in array.
How to get JSON format from array? This is my JSON formatter
{
"productName": "Lemonade",
"transaction": ["[2016-08-01 10:23:42] - Get product in warehouse",
"[2016-08-01 10:53:22] - Sent to customer"]
}
I have an error with this code. I don't know how to get JSON format from transaction array.
if let jsonObject = try JSONSerialization.jsonObject(with: returnData, options: .allowFragments) as? [String: AnyObject]
{
valSucceeded = (jsonObject["succeeded"] as? Bool)!;
valResponseCode = (jsonObject["responseCode"] as? String)!;
valResponseDescription = (jsonObject["responseDescription"] as? String)!;
valSerialNumber = (jsonObject["serialNumber"] as? String)!;
valProductName = (jsonObject["productName"] as? String)!;
if let transactionsArray = jsonObject["transactions"] as? Array<AnyObject> {
for transact in transactionsArray
{
if let transactionStr = transact["transactions"] as? String {
valTransactions = transactionStr
} else {
valTransactions = ""
}
}
}
let entryResult = TraceModel(succeeded: valSucceeded,
responseCode: valResponseCode,
responseDescription: valResponseDescription,
serialNumber: valSerialNumber,
productName: valProductName,
transactions: valTransactions);
traceArray.append(entryResult);
}
I have made the following function in Swift 3:
func parseJSON() {
var JsonResult: NSMutableArray = NSMutableArray()
do {
JsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSMutableArray
} catch let error as NSError {
print(error)
}
var jsonElement:NSDictionary=NSDictionary()
let locations: NSMutableArray = NSMutableArray()
for i in 0 ..< JsonResult.count
{
jsonElement = JsonResult[i] as! NSDictionary
let location = Parsexml()
if let title = jsonElement["Title"] as? String,
let body = jsonElement["Body"] as? String,
let userId = jsonElement["UserId"] as? Int,
let Id = jsonElement["Id"] as? Int
{
location.title = title
location.body = body
location.userId = userId
location.id = Id
}
locations.add(location)
}
DispatchQueue.main.async { () -> Void in
self.delegate.itemsDownloaded(items: locations)
}
When i call this function from another method, i get the following error:
Could not cast value of type '__NSArrayI' (0x105d4fc08) to 'NSMutableArray' (0x105d4fcd0).
It points me towards the element here:
JsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSMutableArray
Where it exits with a SIGBRT..
What have i missed here?
You are trying to convert an NSArray into an NSMutable array which is what the warning is complaining about.
Take the array it provides you, and then convert it into a mutable one.
let jsonArray = try JSONSerialization.jsonObject(with: self.data as Data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
jsonResult = jsonArray.mutableCopy() as! NSMutableArray
Unrelated, but you may also want to user a lower case value for the JsonResult to fit with normal iOS style guidelines. It should instead be jsonResult.
Another way to improve your code:
You are not mutating your JsonResult, so you have no need to declare it as NSMutableArray:
var JsonResult = NSArray()
do {
JsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
} catch let error as NSError {
print(error)
}
And some steps to improve your code...
enum MyError: Error {
case NotArrayOfDict
}
func parseJSON() {
do {
guard let jsonResult = try JSONSerialization.jsonObject(with: self.data as Data) as? [[String: Any]] else {
throw MyError.NotArrayOfDict
}
let locations: NSMutableArray = NSMutableArray()
for jsonElement in jsonResult {
let location = Parsexml()
if let title = jsonElement["Title"] as? String,
let body = jsonElement["Body"] as? String,
let userId = jsonElement["UserId"] as? Int,
let Id = jsonElement["Id"] as? Int
{
location.title = title
location.body = body
location.userId = userId
location.id = Id
}
locations.add(location)
}
DispatchQueue.main.async { () -> Void in
self.delegate.itemsDownloaded(items: locations)
}
} catch let error {
print(error)
}
}
as! casting sometimes crashes your app, use it only when you are 100%-sure that the result is safely converted to the type. If you are not, using guard-let with as? is safer.
Use Swift types rather than NSSomething as far as you can.
Specifying .allowFragments is not needed, as you expect the result as an Array.
And if you can modify some other parts of your code, you can write your code as:
func parseJSON() {
do {
//If `self.data` was declared as `Data`, you would have no need to use `as Data`.
guard let jsonResult = try JSONSerialization.jsonObject(with: self.data) as? [[String: Any]] else {
throw MyError.NotArrayOfDict
}
var locations: [Parsexml] = [] //<-Use Swift Array
for jsonElement in jsonResult {
let location = Parsexml()
if let title = jsonElement["Title"] as? String,
let body = jsonElement["Body"] as? String,
let userId = jsonElement["UserId"] as? Int,
let Id = jsonElement["Id"] as? Int
{
location.title = title
location.body = body
location.userId = userId
location.id = Id
}
locations.append(location)
}
DispatchQueue.main.async { () -> Void in
self.delegate.itemsDownloaded(items: locations)
}
} catch let error {
print(error)
}
}
I am getting the following JSON from Foursquare API and I have been struggling with extracting the data:
{
"meta":{
"code":200,
"requestId":"58122e59498e5506a1b23580"
},
"response":{
"venues":[
{
"id":"4d56c381a747b60cd4a12c2b",
"name":"Sports Circle",
"contact":{},
"location":{
"lat":31.9,
"lng":35.9,
"labeledLatLngs":[
{
"label":"display",
"lat":31.9,
"lng":35.90
}
],
],
"confident":true
}
}
}
I want to get the name in venues in addition to the lat and lng values. I have tried this so far but it gets out of the second if statement at JVenues because it is nil:
func parseData (JSONData: Data){
do {
var readableJson = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! [String:AnyObject]
if let JResponse = readableJson ["response"] as? [String:AnyObject] {
if let JVenues = JResponse["venues"] as? [String:AnyObject]{
if let JName = JVenues["name"] as? String{
NSLog(JName)
}
}
}
} catch {
print(error)
}
}
This is what the other answers are getting at. Will probably make more sense if you can see it all laid out...
if let JResponse = readableJson ["response"] as? [String : AnyObject] {
if let JVenues = JResponse["venues"] as? [[String : AnyObject]] {
if let JName = JVenues.first?["name"] as? String {
NSLog(JName)
}
}
}
Note this only gets the FIRST name in the array of venues.
EDIT:
I prefer something like this. Define a struct and convert your dictionaries to the struct:
struct Venue {
var name: String?
var venueId: String?
init(_ venueDictionary: [String : AnyObject]) {
self.name = venueDictionary["name"] as? String
self.venueId = venueDictionary["id"] as? String
}
}
In your class create a property such as:
var venues = [Venue]()
From your JSON map the dictionaries to the venue array. I renamed variables that start with a capital for convention.
if let response = readableJson ["response"] as? [String : AnyObject] {
if let responseVenues = response["venues"] as? [[String : AnyObject]] {
self.venues = responseVenues.map({ Venue($0)) })
}
}
Use anywhere in your class like:
let venue = self.venues.first
print(venue?.name)
Or:
if let venue = self.venues.find({ $0.name == "Sports Circle" }) {
print("found venue with id \(venue.venueId)")
}
I am new on swift and I am getting a json back from a request but I can not parse. I am trying to get the json info and create coordinates to use on mapkit with annotations as well
Below is the json I get back
{
coord = [
{
islocationactive = 1;
latitude = "37.8037522";
locationid = 1;
locationsubtitle = Danville;
locationtitle = "Schreiner's Home";
longitude = "121.9871216";
},
{
islocationactive = 1;
latitude = "37.8191921";
locationid = 2;
locationsubtitle = "Elementary School";
locationtitle = Montair;
longitude = "-122.0071005";
},
{
islocationactive = 1;
latitude = "37.8186077";
locationid = 3;
locationsubtitle = "Americas Eats";
locationtitle = "Chaus Restaurant";
longitude = "-121.999046";
},
{
islocationactive = 1;
latitude = "37.7789669";
locationid = 4;
locationsubtitle = "Cheer & Dance";
locationtitle = Valley;
longitude = "-121.9829908";
}
] }
and my code to try to parse is this
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
//exiting if there is some error
if error != nil{
print("error is \(error)")
return;
}
//parsing the response
do {
//converting resonse to NSDictionary
var teamJSON: NSDictionary!
teamJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
print(teamJSON)
//getting the JSON array teams from the response
let liquidLocations: NSArray = teamJSON["coord"] as! NSArray
//looping through all the json objects in the array teams
for i in 0 ..< liquidLocations.count{
//getting the data at each index
// let teamId:Int = liquidLocations[i]["locationid"] as! Int!
}
} catch {
print(error)
}
}
//executing the task
task.resume()
but not that I try works. I want to get the latitude, longitude and create an annotationn on the map
Thanks for the help
You can try with below code its same as #Niko Adrianus Yuwono but made some changes so you will get teamid as integer
do {
let data : NSData = NSData() // change your data variable as you get from webservice response
guard let teamJSON = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: Any],
let liquidLocations = teamJSON["coord"] as? [[String: Any]]
else { return }
//looping through all the json objects in the array teams
for i in 0 ..< liquidLocations.count{
let teamId: Int = (liquidLocations[i]["locationid"] as! NSString).integerValue
print(teamId)
}
} catch {
print(error)
}
Try this
do {
guard let teamJSON = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any],
let liquidLocations = teamJSON["coord"] as? [[String: Any]]
else { return }
//looping through all the json objects in the array teams
for i in 0 ..< liquidLocations.count{
let teamId: Int = (liquidLocations[i]["locationid"] as! NSString).integerValue
}
} catch {
print(error)
}
The key is not to use NSDictionary and NSArray because it's not strongly-typed (Although you can make it strongly-typed too) use Swift's array and Dictionary where you can use [Element Type] for array and [Key: Value] for dictionary