how to get the JSONArray from jsonObject in Swift 3.1 - ios

{
"status": true,
"status_code": 1,
"content": [
{
"cat_id": "3",
"cat_name": "Food",
"cat_parentid": "2"
},
{
"cat_id": "4",
"cat_name": "Entertainment",
"cat_parentid": "2"
},
{
"cat_id": "5",
"cat_name": "Cars",
"cat_parentid": "2"
},
{
"cat_id": "12",
"cat_name": "Personal Care",
"cat_parentid": "2"
}
],
"message": "Success"
}
UPDATE
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
completion((json as? AnyObject)!) //here completion callback will return the jsonObject to my UIViewController.
}
} catch let error {
print(error.localizedDescription)
}
this is my JSONObject. I am very new to the swift. how to get the content JSONArray and further process in swift.? Anybody can help me? Help will be appreciated.

This code checks if the status is true, gets the array for key content and prints all values in the array.
The array is clearly [[String:String]] so cast the object to this specific type.
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
if let status = json["status"] as? Bool, status == true {
if let content = json["content"] as? [[String:String]] {
for category in content {
let id = category["cat_id"]
let name = category["cat_name"]
let parentId = category["cat_parentid"]
print(id , name, parentId)
}
}
}
}
} catch let error {
print(error.localizedDescription)
}
PS: As always, never use .mutableContainers in Swift. It's meaningless

Check whether your json has content array
if let content = json["content"] as? [Dictionary<String, AnyObject>] {
print(content) // it will give you content array
}

Get content array like this:
let allContent = json["content"] as? [[String: Any]]
Full sample:
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
if let allContent = json["content"] as? [[String: Any]] {
for content in allContent {
let catId = content["cat_id"] as? String
let catName = content["cat_name"] as? String
let catParentId = content["cat_parentid"] as? String
print(">> catid=" + catId!)
print(">> catName=" + catName!)
print(">> catparentID=" + catParentId!)
}
}
}
} catch let error {
print(error.localizedDescription)
}

let content = dict.objectForKey("content")! as NSArray
Then you can get json of single object for parsing by
for var cat in content
{
print(cat)
}

Another alternative way, by using the library.
First, import JSON library for Swift - SwiftyJSON and use the code:
import SwiftyJSON
let json = JSON(<jsonObject data>)
let contentArray: Array<JSON> = json["content"].arrayValue
Library Integration
If you're using cocoapods then use this pod:
pod 'SwiftyJSON'
OR else just drag SwiftyJSON.swift to the project tree.

you can extract you data by providing key
if let array = result["content"] as? Array<AnyObject> {
print(arry)
}

You can access like below
if let filePath = Bundle.main.path(forResource: "sample", ofType: "json"), let data = FileManager().contents(atPath: filePath) {
do {
let dicRes = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
let contentArray = dicRes?["content"]
print("contentArray == \(contentArray)")
} catch {
}
}

Related

How can I decode JSON with array and more JSON inside?

I recently began with swift. I need decode the json on below.
The JSON has inside two more JSON the first one (validation) does not matter. The second one (result) has a JSON array inside (serviceCenter). I need the information of each servicenter. I try to use servicecenter as decodeable class to get a servicenter object, but as the JSON does not have the proper format I can't do it.
[
{
"validation": {
"bValid": true,
"sDescription": "Access true."
}
},
{
"result": {
"serviceCenter": [
{
"model": "Vanquish",
"color": "Purple",
"make": "Aston Martin",
"sTag": "3666",
"sVin": "6JDO2345",
"sMiles": "3666",
"bDamage": "1",
"dDateTime": "04-17-2018 9:38 AM"
},
{
"model": "F360",
"color": "Red",
"make": "Ferrari",
"sTag": "0010",
"sVin": "6JDO2347",
"sMiles": "80000",
"bDamage": "1",
"dDateTime": "04-17-2018 9:25 AM"
},
{
"model": "Vanquish",
"color": "Purple",
"make": "Aston Martin",
"sTag": "0009",
"sVin": "6JDO2345",
"sMiles": "25000",
"bDamage": "1",
"dDateTime": "04-17-2018 9:23 AM"
},
{
"model": "Vanquish",
"color": "Purple",
"make": "Aston Martin",
"sTag": "0003",
"sVin": "6JDO2345",
"sMiles": "20000",
"bDamage": "1",
"dDateTime": "04-12-2018 10:37 AM"
}
]
}
}
]
I try so much but i cant do it.
This its my code now, Could someone help me please
do {
let parseoDatos = try JSONSerialization.jsonObject(with: data!) as! [AnyObject]
let h = type(of: parseoDatos )
print("'\(parseoDatos)' of type '\(h)'")
let contenido = parseoDatos[1]["result"]
if let services = contenido!! as? Dictionary<String, Array<Any>> {
for (_,serviceArray) in services {
for sc in serviceArray{
let h = type(of: sc )
print("'\(sc)' of type '\(h)'")
}
}
}
} catch {
print("json processing failed")
}
the result of print sc is
{
bDamage = 1;
color = Purple;
dDateTime = "04-17-2018 9:38 AM";
make = "Aston Martin";
model = Vanquish;
sMiles = 3666;
sTag = 3666;
sVin = 6JDO2345;
}' of type '__NSDictionaryI'
You can use Codable
Initial response have array of InitialElement and InitialElement is is struct with validation , result , result may be nil
don't forget to add your URL at url
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if let initial = try? JSONDecoder().decode([InitialElement].self, from: data){
// inital now have array of InitialElement and InitialElement is is struct with validation , result , result may be nil
print(initial)
}
}.resume()
With this Model for Data:
import Foundation
struct InitialElement: Codable {
let validation: Validation?
let result: ResultData?
}
struct ResultData: Codable {
let serviceCenter: [ServiceCenter]
}
struct ServiceCenter: Codable {
let model, color, make, sTag: String
let sVin, sMiles, bDamage, dDateTime: String
}
struct Validation: Codable {
let bValid: Bool
let sDescription: String
}
extension InitialElement {
init(data: Data) throws {
self = try JSONDecoder().decode(InitialElement.self, from: data)
}
}
try this code
enum ParsingError: Error {
case wrongFormat(String)
}
do {
let jsonObject = try JSONSerialization.jsonObject(with: data!)
guard let array = jsonObject as? [Any] else {
throw ParsingError.wrongFormat("wrong root object")
}
guard array.count == 2 else {
throw ParsingError.wrongFormat("array count != 2")
}
guard let dict = array[1] as? [String: Any] else {
throw ParsingError.wrongFormat("can't parse dict from array")
}
guard let serviceCenters = (dict["result"] as? [String: Any])?["serviceCenter"] else {
throw ParsingError.wrongFormat("can't parse serviceCenters")
}
guard let serviceCentersArray = serviceCenters as? [[String : Any]] else {
throw ParsingError.wrongFormat("serviceCenters is not an array")
}
print("\(type(of: serviceCentersArray))\n", serviceCentersArray)
} catch {
print("json processing failed: \(error)")
}
Thanks all for yours answers, it's my first question here, and i feels great all the help. Finally i can resolve the problem. Maybe not the best way, but here its the code:
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil{
print("error=\(String(describing: error))")
return
}
do {
let parseoDatos = try JSONSerialization.jsonObject(with: data!) as! [AnyObject]
let h = type(of: parseoDatos )
print("'\(parseoDatos)' of type '\(h)'")
let contenido = parseoDatos[1]["result"]
if let services = contenido!! as? Dictionary<String, Array<Any>> {
for (_,serviceArray) in services {
for sc in serviceArray{
let h = type(of: sc )
print("'\(sc)' of type '\(h)'")
let valid = JSONSerialization.isValidJSONObject(sc) // true
print(valid)
do {
let jsonData = try JSONSerialization.data(withJSONObject: sc, options: .prettyPrinted)
let serviceDecoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
if let scJSON = serviceDecoded as? [String:String] {
print ("--------------------------")
print("'\(scJSON)' of type '\(type(of: scJSON))'")
print ("--------------------------")
}
} catch {
print(error.localizedDescription)
}
i think later y try to use Codable as suggested, but for now the code is working ok. Thanks again!
//try this it is working
let arrayMain=try?JSONSerialization.jsonObject(with:jsonData!,options:.mutableLeaves) as! Array<Any>
//print(arrayMain!)
if let firstDictionart=arrayMain![0] as? [String: Any] {
if let insideFirstDict = firstDictionart["validation"] as? [String: Any]{
print(insideFirstDict["bValid"]!)
print( insideFirstDict["sDescription"]!)
}
}
if let resultDictionary=arrayMain![1] as? [String: Any] {
if let serviceDictionary = resultDictionary["result"] as? [String: Any] {
for array in serviceDictionary["serviceCenter"] as! Array<Any>{
if let infoDicti=array as? [String: Any] {
print( infoDicti["color"]!)
print( infoDicti["make"]!)
print( infoDicti["color"]!)
print( infoDicti["sTag"]!)
print( infoDicti["sVin"]!)
print( infoDicti["sMiles"]!)
print( infoDicti["sVin"]!)
print( infoDicti["model"]!)
print( infoDicti["bDamage"]!)
print( infoDicti["dDateTime"]!)
}
}
}
}

Parsing json string crashes

I'm trying to parse a json string:
if let jsonStr = asd.value(forKey: "orderData") as? String {
print(jsonStr)
let data = jsonStr.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject] // CRASHES HERE
if let names = json["product_name"] as? [String] {
print(names)
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
}
But at the line let json = try JSONSeri... it crashes saying Could not cast value of type '__NSArrayI' to 'NSDictionary'.
Also tried changing this as! [String: AnyObject] to as! [[String: AnyObject]]. But it still doesn't work.
This is my json string structure:
[
{
"product_id" : "1",
"category_json" : {
"category_id" : "1",
"category_name" : "nvm"
},
"selling_price" : "200",
"product_name" : "nvm",
},
{
"product_id" : "2",
"category_json" : {
"category_id" : "2",
"category_name" : "cas"
},
"selling_price" : "800",
"product_name" : "cas",
}
]
You should not be force casting with ! unless you are 100% sure that it will succeed.
I would suggest you use the following:
let jsonArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]]
This will return you a list of products. If you want a list of the product names than you need to iterate over it and extract the product name of each item. You can do this like so:
let names = jsonArray.map({ $0["product_name"] as? String })
As already mentioned the object is an array, you have to use a for loop to get all items
...
let data = Data(jsonStr.utf8)
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [[String: Any]] {
for item in json {
if let name = item["product_name"] as? String {
print(name)
}
}
}
} catch {
print("Failed to load: \(error.localizedDescription)")
}

Swift JSONSerialization as NSDictionary can't get to values inside

JSON Results from output This image should help I am trying to get to [9] "vehicleLocation"
I have an API from UTA that tracks transit data in real-time and displays JSON data
let url = URL(string: "UTA API")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
AlertController.showAlert(_inViewController: self, title: "Error", message: ("Fatal Error"))
} else {
if let urlContent = data {
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
print(jsonResult)
//get to item within dictionary
let speed = jsonResult["speed"] as? [String:Any]
print(speed)
} catch {
AlertController.showAlert(_inViewController: self, title: "Error", message: "JSON Processing Failed")
}
}
}
}
task.resume()
this returns JSON data:
{
"serviceDelivery": {
"vehicleMonitoringDelivery": {
"vehicleActivity": [
{
"monitoredVehicleJourney": {
"extensions": {
"lastGPSFix": "2017-11-27T23:58:28.083",
"speed": 5.8690799999999994
},
I want the speed value and display in a label. But it comes up nil.
Any ideas and help would be welcomed.
Thanks
Looks like you're trying to access value with key speed at the first level, but it's actually way lower in the hierarchy, beyond a lot of children.
let dic = value[keyPath: "serviceDelivery.vehicleMonitoringDelivery"]
let array = dic["vehicleActivity"] as? NSArray
for speedValueDic in array{
let speed = speedValueDic["speed"] as? String
print(speed)
}
first try to access high level objects then when you reach speed cast it as string not as dictionary this will get you the value
let jsonString = "{\"device\":\"iPhone 6\",\"OS\":\"iOS 9\",\"name\":\"Apple\"}"
let data = jsonString.data(using: .utf8)
let json = try JSONSerialization.jsonObject(with: data!) as? [String : Any]
print (json!["name"] as! String)
var arrVehicleActivity = jsonResult["serviceDelivery"]?["vehicleMonitoringDelivery"]?["vehicleActivity"] as? [Any]
for i in 0..<arrVehicleActivity?.count {
var strSpeed = arrVehicleActivity?[i]?["monitoredVehicleJourney"]?["extensions"]?["speed"] as? String
print("Output should be speed :\(strSpeed)")
}
Hope will helpful to you!!
print("Output should be speed :(strSpeed)")
Output should be speed : 5.8690799999999994

How to parse JSON using Alamofire in Swift 3.0 without any third-party library

Here I want to parse JSON via url. This is what actual JSON data available on url. So I need to parse it and read in my app using Alamofire. But I 'm unable to do it.
JSON Data in my url.
{
"main": [
{
"date": "2017-01-11",
"USDARS": "15.8302",
"USDCLP": "670.400024",
"USDSDG": "6.407695"
},
{
"date": "2017-01-12",
"USDARS": "15.804999",
"USDCLP": "661.599976",
"USDSDG": "6.407697"
},
{
"date": "2017-01-13",
"USDARS": "15.839041",
"USDCLP": "659.200012",
"USDSDG": "6.407704"
},
{
"date": "2017-01-14",
"USDARS": "15.839041",
"USDCLP": "659.200012",
"USDSDG": "6.407704"
}
]
}
How do I read it using Alamofire in swift 3.0
Below is what actually I'm trying to parse above JSON data via url.
Alamofire.request("myurl") .responseJSON { response in
print("In Alamofire")
if let arr = response.result.value as? [String:AnyObject]
{
if let arr = response.result.value as? [NSDictionary]
{
let val1 = (arr["main"]["USDARS"] as? String)
print(val1)
//It does not print any thing.
}
}
}
Please help me. I'm new to it.
Top level json is [String:Any] and main is an array i.e. [[String:String]]
Alamofire.request("myurl") .responseJSON { response in
if let result = response.result.value as? [String:Any],
let main = result["main"] as? [[String:String]]{
// main[0]["USDARS"] or use main.first?["USDARS"] for first index or loop through array
for obj in main{
print(obj["USDARS"])
print(obj["date"])
}
}
}
You should use SwiftyJson, which is a library for json parsing, very usefull with Alamofire
In your case you can do something like this with swiftyJson :
//Array & Dictionary
var jsonArray: JSON = [
"main": ["date": "2017-01-11", "USDARS": "15.8302"]
]
let dateString = jsonArray["main"][0]["date"].string
print(dateString) = "2017-01-11"
#IBAction func btnget(_ sender: UIButton) {
let urlpath : String = "http://202.131.123.211/UdgamApi_v4/App_Services/UdgamService.asmx/GetAllTeacherData?StudentId=2011111"
let url = URL(string: urlpath)
var urlrequest = URLRequest(url: url!)
urlrequest.httpMethod = "GET"
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: urlrequest) { (data, response, error) in
do {
guard let getResponseDic = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: AnyObject] else {
print("error trying to convert data to JSON")
return
}
// now we have the todo, let's just print it to prove we can access it
print(getResponseDic as NSDictionary)
let dic = getResponseDic as NSDictionary
let msg = dic.object(forKey: "message")
print(dic)
//let arrObj = dic.object(forKey: "teacherDetail") as! NSArray
//print(arrObj)
//let arr = dic.value(forKey: "TeacherName")as! NSArray
print(((dic.value(forKey: "teacherDetail") as! NSArray).object(at: 0) as! NSDictionary).value(forKey: "TeacherName") as! String)
// the todo object is a dictionary
// so we just access the title using the "title" key
// so check for a title and print it if we have one
// print("The title is: " + todoTitle)
} catch {
print("error trying to convert data to JSON")
return
}
} task.resume()
}

Swift json delete key

I want to parsing my json file without "results" tab my new json file
[
{
"Id": 708,
"Name": "My name",
"ImageUrl": "2016728135316.jpg"
}
Codes under below
private func getMoviesFromJSON(jsonData: NSData) throws -> [Movie] {
var movies = [Movie]()
do {
if let jsonObject = try NSJSONSerialization.JSONObjectWithData(jsonData, options: .AllowFragments) as? [String: AnyObject], jsonArray = jsonObject["results"] as? [[String: AnyObject]] {
for i in jsonArray {
var properties = [String: AnyObject]()
properties[JSONKeys.id] = i[JSONKeys.id]
properties[JSONKeys.title] = i[JSONKeys.title]
properties[JSONKeys.posterPath] = i[JSONKeys.posterPath]
let movie = Movie(properties: properties)
movies.append(movie)
}
}
} catch {
throw TMDBErrors.ParsingError
}
return movies
}
I think must be change this line or must be delete.
jsonObject["results"]
I need your help , Thank You !
Your json doesn't have any results parameter .. so you don't need it at all ..
do {
if let jsonArray = try NSJSONSerialization.JSONObjectWithData(jsonData, options: .AllowFragments) as? [[String: AnyObject]] {
for i in jsonArray {
var properties = [String: AnyObject]()
properties[JSONKeys.id] = i[JSONKeys.id]
properties[JSONKeys.title] = i[JSONKeys.title]
properties[JSONKeys.posterPath] = i[JSONKeys.posterPath]
let movie = Movie(properties: properties)
movies.append(movie)
}
}
} catch {
throw TMDBErrors.ParsingError
}

Resources