SWIFT 2: Loop through JSON array - json

I am getting this json from a url, the return JSON is:
[{"id":1,"name":"Mary"},{"id":2,"name":"John"}]
I want to display the names in a TableView on IOS.
My Swift2 Code is:
class ViewController: UIViewController, UITableViewDelegate {
var NumberOfPersons = 0
var NameOfPerson = [String]()
override func viewDidLoad() {
super.viewDidLoad()
parseJSON()
}
func parseJSON(){
do {
let data = NSData(contentsOfURL: NSURL(string: "http://zzzzzz.com/API/name.php")!)
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
let NumberOfPersons = jsonResult.count
**LOOP THROUGH THE JSON ARRAY**
} catch let error as NSError {
print(error)
}
}
}
How can I loop through the JSON array to put which name in a cell on a Table View?

The variable jsonResult is an array of dictionaries, so you can loop through the array with
for anItem in jsonResult as! [Dictionary<String, AnyObject>] { // or [[String:AnyObject]]
let personName = anItem["name"] as! String
let personID = anItem["id"] as! Int
// do something with personName and personID
}
In Swift 3 the unspecified JSON type has been changed to Any
for anItem in jsonResult as! [Dictionary<String, Any>] { ... // or [[String:Any]]

make the JSON results in a DICT and get it with a loop "for (key, value)"

If your is finally
let jsonResult = [{"id":1,"name":"Mary"},{"id":2,"name":"John"}]
var jsonDictResult[String: Int] = jsonResult;
Updated:
let jsonResult: AnyObject? = NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions.AllowFragments,
error:&parseError)
Updated:
Make the JSON results in a DICT and get it with a loop "for (key, value)"

let jsonResult: AnyObject? = NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions.AllowFragments,
error:&parseError)

Related

Swift nested JSON Objects not decoding

I'm trying to decode an array of nested objects within Swift and it's not working. The nested objects are of the same type which I'm using Realm to store the values and look like:
struct myObject: Codable {
var name: String?
let otherObjects = List<myObject>()
var events: [String]?
...
if let objects = try container.decodeIfPresent([myObject].self, forKey: .otherObjects) {
otherObjects.append(objectsIn: objects)
}
}
Decoder Function - This works for all other fields inside the object at top level including events which is an array of String.
static func decodeResponse<T:Codable>(_ response : Any?) -> T? {
if let response = response, let dict = response as? [String:Any] {
var dictionaryToParse = dict
var arrayToParse: [[String:Any]]?
if let dataObject = dict["data"] as? [String:Any] {
//sometimes the response has an outer "data" OBJECT
dictionaryToParse = dataObject
} else if let dataArray = dict["data"] as? [[String:Any]] {
//sometimes the response has an outer "data" ARRAY
arrayToParse = dataArray
}
do {
guard let data = try? JSONSerialization.data(withJSONObject: arrayToParse ?? dictionaryToParse, options: []) else { return nil }
let obj = try JSONDecoder().decode(T.self, from: data)
print("DECODE: \(obj)")
return obj
}
catch let error {
print("ERROR: (decodeResponse): \(error)")
return nil
}
}
return nil
}
The coding keys map as they're the same type and nothing gets outputted as an error.

How to store NSArray in Userdefaults?

Here is my code
var defaultValues = UserDefaults.standard
var json = NSArray()
self.defaultValues.set(json, forKey: "BedData")
I used this Code to store Strings and it works perfectly but when i tried to store NSArray it gives me this error "Attempt to insert non-property list object"
You have to encode and decode for adding and retrieving data to/from UserDefault.
func getUserDetail() -> UserDetail? {
if let decodedData = UserDefaults.standard.object(forKey: AppConstant.userDefaultKey.user_detail) as? Data {
return try! PropertyListDecoder().decode(UserDetail.self, from: decodedData)
}
return nil
}
func setUserDetail(user: UserDetail) {
UserDefaults.standard.set(try! PropertyListEncoder().encode(user), forKey: AppConstant.userDefaultKey.user_detail)
}
Thanks for the replies Guys But i have found the solution
Let json = NSArray()
To Store
let data = NSKeyedArchiver.archivedData(withRootObject: json)
self.defaultValues.set(data, forKey: "Offline-BedData")
And to Retrieve:
if let data = self.defaultValues.object(forKey: "Offline-BedData")! as? Data {
if let dict = NSKeyedUnarchiver.unarchiveObject(with: data) as? NSArray {
json = dict
print("json\(json)")
self.performSegue(withIdentifier: "BedShow", sender: Any?.self)
}
}

Swift JSONSerialization.jsonObject Error

I've looked around but I don't find an answer to fix this error that has been bugging me. I tried adding a "as! NSMutableArray" but that gave me another error. Any ideas on how to fix it? I converted my project from Objective-C to Swift, so hopefully the code is all good I had 20+ errors now I'm down to 3 errors. Thank you.
Error Message:
'jsonObject' produces 'Any', not the expected contextual result type 'NSMutableArray'
Code for retrieving data from server
// Retrieving Data from Server
func retrieveData() {
let getDataURL = "http://ip/example.org/json.php"
let url: NSURL = NSURL(string: getDataURL)!
do {
let data: NSData = try NSData(contentsOf: url as URL)
jsonArray = JSONSerialization.jsonObject(with: data, options: nil)
}
catch {
print("Error: (data: contentsOf: url)")
}
// Setting up dataArray
var dataArray: NSMutableArray = []
// Looping through jsonArray
for i in 0..<jsonArray.count {
// Create Data Object
let dID: String = (jsonArray[i] as AnyObject).object(forKey: "id") as! String
let dName: String = (jsonArray[i] as AnyObject).object(forKey: "dataName") as! String
let dStatus1: String = (jsonArray[i] as AnyObject).object(forKey: "dataStatus1") as! String
let dStatus2: String = (jsonArray[i] as AnyObject).object(forKey: "dataStatus2") as! String
let dURL: String = (jsonArray[i] as AnyObject).object(forKey: "dataURL") as! String
// Add Data Objects to Data Array
dataArray.add(Data(dataName: dName, andDataStatus1: dStatus1, andDataStatus2: dStatus2, andDataURL: dURL, andDataID: dID))
}
self.myTableView.reloadData()
}
The jsonObject function will return a value of type Any but the jsonArray's type of NSMutableArray. And this function will throw an error if something is wrong, put a try keyword before it. In my experience, let change the type of jsonArray to array of dictionary, so you will extract data with ease.
do {
let data: Data = try Data(contentsOf: url as URL)
let jsonArray: [[String: AnyObject]] = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [[String: AnyObject]]
print("json: \(jsonArray)")
for dict in jsonArray {
let dataName = dict["dataName"] as! String
print("dataName: \(dataName)")
}
}
catch {
print("Error: (data: contentsOf: url)")
}

How do I get a specific value from returned json in Swift 3.0?

I am trying to get a value from json in Swift. I have added an image of the data tree. My previous attempts have not worked. Below is code which prints the full json object which is what I don't want.
json tree image
import PlaygroundSupport
import UIKit
let url = URL(string: "https://api.data.gov.sg/v1/transport/taxi-availability")
var request = URLRequest(url: url!);
request.addValue("xxxx", forHTTPHeaderField: "api-key")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
print(error)
return
}
guard let data = data else {
print("Data is empty")
return
}
let json = try! JSONSerialization.jsonObject(with: data, options: [])
//print(json)
}//end
//["features"]??[0]?
task.resume()
PlaygroundPage.current.needsIndefiniteExecution = true
You just need to do something with the json you've been vended:
let task = URLSession ... { data, response, error in
let json = JSONSerialization.jsonObject(...)
if let json = json as? [String: Any] {
// now you have a top-level json dictionary
for key, value in json {
print("json[\"\(key\")] = \(value)")
}
}
}
I didn't verify the following code but it should work for the son tree you provided. (disclaimer: might have some errors but its mostly correct)
if let json = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String:Any]
, let features = json["features"] as? [Any]
, let firstFeature = features[0] as? [String:Any]
, let properties = firstFeature["properties"] as? [String:Any]
, let taxiCount = properties["taxi_count"] as? Int
{
print(taxiCount)
}
If Json is dictionary
let json = try! JSONSerialization.jsonObject(with: data, options: [])
let jsonDict = json as? NSDictionary
//if you have a key name
let name = jsonDict["name"] as? String
//and so on
//if you have a array in your dictionary
let likes = jsonDict["likes"] as? NSArray
let numberOfLikes = likes.count
for eachLike in likes {
let likerName = eachLike["liker_name"] as? String
}

Error when try to parse json?

I'm trying to parse JSON, but it's not working. I want to get id from the JSON at the URL, but it shows me null value.
var names = [String]()
var SearchURL = "http://ios.khothe.vn/web/gamecards/authenticate/user/dungphiau/pass/829d81d46bad96825dc52a6e1675aab0"
typealias jsonStandard = [String : AnyObject]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
callAlamo(url: SearchURL)
}
func callAlamo(url : String) {
Alamofire.request(url).responseJSON(completionHandler:
{
responds in
self.parseData(JsonData: responds.data!)
})
}
func parseData(JsonData : Data) {
do{
var readableJson = try JSONSerialization.jsonObject(with: JsonData, options: .mutableContainers) as! jsonStandard
let tracks = readableJson["id"] as? jsonStandard
print(tracks)
} catch{
print(error)
}
}
The value for key id is String not [String:AnyObject] aka jsonStandard
let tracks = readableJson["id"] as? String
Consider that in Swift 3 the type of a JSON dictionary is [String:Any]
typealias jsonStandard = [String : Any]