Swift: Parsing Arrays out of JSONs - arrays

[{"name":"Air Elemental","toughness":"4","printings":["LEA","BTD","7ED","8ED","9ED","10E","DD2","M10","DPA","ME4","DD3_JVC"]}]
I have a JSON where there is an array in each listing called "printings" as seen below, how would I take this array out of each listing and convert it into a string like "LEA-BTD-7ED". Here is what I have so far but its crashing.
let err : NSErrorPointer?
let dataPath = NSBundle.mainBundle().pathForResource("cardata", ofType: "json")
let data : NSData = try! NSData(contentsOfFile: dataPath! as String, options: NSDataReadingOptions.DataReadingMapped)
do{
var contents = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments) as! [AnyObject]
for var i = 0;i<contents.count;++i{
let printing = contents[i]["printings"] as! String
}
}

Here's the code:
let path = dataPath!
if let JSONData = NSData(contentsOfFile: path)
{
do
{
if let dictionariesArray = try NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions()) as?
[[String: AnyObject]]
{
for dictionary in dictionariesArray
{
if let printingsArray = dictionary["printings"] as? [String]
{
let printingsString = printingsArray.joinWithSeparator("-")
print(printingsString)
}
}
}
}
catch
{
print("Could not parse file at \(path)")
}
}
Executing it prints "LEA-BTD-7ED-8ED-9ED-10E-DD2-M10-DPA-ME4-DD3_JVC"

You can't cast an Array (contents[i]["printings"]) to a String. What you want is Array's joinWithSeparator() method, like this:
let printing = contents[i]["printing"] as! Array
let printingStr = printing.joinWithSeparator("-")
(Actually, I'm not sure whether you need the as! Array; try it without it.)

Related

Swift3 get element from array

I have a json string converted to string array like below:
let str = "{ \"dtResult\": [ { \"itmdtl_item_no\": \"AO406705959SE3\" }, { \"itmdtl_item_no\": \"AO406708959SE3\" } ] }"
let data = str.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
let result = json["dtResult"] as? [[String:Any]] ?? [ ]
let item = result[0] as! [String:Any]
print(item)
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
When i print out the result of item, i got the value like this:
["itmdtl_item_no": AO406705959SE3]
But i just want the string "AO406705959SE3", how can i do? Thanks.
First of all don't write
let result = json["dtResult"] as? [[String:Any]] ?? [ ]
If result is nil or empty the app will crash on result[0]
Instead write to check if the array exists and is not empty
if let result = json["dtResult"] as? [[String:Any]], !result.isEmpty {
let item = result[0] as! [String:Any]
// Now get the value for key "itmdtl_item_no"
if let itemNo = item["itmdtl_item_no"] as? String {
print(itemNo)
}
}

Swift Array sort with JSON

Data:
tried get data from JSON
has code with Swift run on Playground
var roadWayStatusArray = [AnyObject]()
let url = URL(string: "http://od.moi.gov.tw/data/api/pbs")
let data = try? Data(contentsOf: url!)
let json = try? JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
if let results = json as? [String : AnyObject] {
if let result = results["result"] as? [[String : AnyObject]] {
for data in result {
let happendate = data["happendate"] as? String
roadWayStatusArray.append(data as AnyObject!)
}
}
}
I has tried using roadWayStatusArray.sort(by: >) but Xcode report me Ambiguous reference member '>'
How to create sort by hapendate or happentime
Your roadWayStatusArray is an array of AnyObject. There is no > operator defined for AnyObject.
The objects in roadWayStatusArray are actually dictionaries that look like this:
{
UID = "10602090007-0";
areaNm = "\U4e2d\U5c71\U9ad8\U901f\U516c\U8def-\U570b\U9053\Uff11\U865f";
comment = "\U5317\U4e0a.\U4e2d\U58e2\U670d\U52d9\U5340 \U51fa\U53e3\U531d\U9053\U4e2d \U53f3\U5074 \U5c0f\U5ba2\U8eca\U505c\U653e\Uff0c\U99d5\U99db\U7591\U4f3c\U7761\U8457\U4e86";
direction = "\U5317\U4e0a";
happendate = "2017-02-09";
happentime = "01:08:00.0000000";
modDttm = "2017-02-09 01:15:43.603";
region = N;
road = "";
roadtype = "\U5176\U4ed6";
srcdetail = "\U71b1\U5fc3\U807d\U773e";
x1 = "121.73558";
y1 = "25.12263";
}
You need to call sort(by:) with a closure that determines the sort order. For example, if you want to sort by happendate and then happentime:
roadWayStatusArray.sort(by: { (lhsAny, rhsAny) -> Bool in
let lhs = lhsAny as? [String: AnyObject]
let rhs = lhsAny as? [String: AnyObject]
let lhsKey = (lhs?["happendate"] as? String ?? "", lhs?["happentime"] as? String ?? "")
let rhsKey = (rhs?["happendate"] as? String ?? "", rhs?["happentime"] as? String ?? "")
return lhsKey < rhsKey
})

how to get array from dictionary in swift 3

I don't understand how to get array from dictionary, i have tried in this code but i want get array only content and type
This is my array
{
wsResponse = {
aarti =(
{
content = "";
identifier = "slok_one";
title = 1;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
},
{
content = "";
identifier = "slok_two";
title = 2;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
},
{
content = "";
identifier = "slok_three";
title = 3;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
}
}
);
};
Here is my code
Alamofire.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default)
.responseJSON { response in
if let status = response.response?.statusCode {
switch(status){
case 201:
print("example success")
default:
print("error with response status: \(status)")
}
}
//to get JSON return value
if let array = response.result.value
{
let JSON = array as! NSDictionary
print("\(JSON)")
let response = JSON["wsResponse"] as! NSDictionary
let data = response["aarti"]
}
}
i want array from this ,like content,title,type
thank you in advance
According to the JSON this prints all values in the aarti array:
if let JSON = response.result.value as? [String:Any] {
if let response = JSON["wsResponse"] as? [String:Any],
let aarti = response["aarti"] as? [[String:Any]] {
for item in aarti {
let content = item["content"] as! String
let identifier = item["identifier"] as! String
let title = item["title"] as! Int
let type = item["type"] as! String
print(content, identifier, title, type)
}
}
}
Basically do not use NSDictionary / NSArray in Swift.
If you want to put all content values in an array use flatMap. The line can replace the whole repeat loop.
let contentArray = aarti.flatMap { $0["content"] as? String }
PS: If you are going to create multiple arrays from the values don't do that: Use a custom struct or class
if someone want to get dictionary of array and use it in tableview
declaration:
var list:[Any] = []
and initialisation :
self.list = (self.ListDic?["data"] as! NSArray!) as! [Any]
and use:
let dictObj = self.list[indexPath.row] as! NSDictionary
print("object value: ",dictObj["text"] as! String)

Swift 2.0 : Json Array Parsing errors

in Swift 1.2
https://gist.github.com/anonymous/a167148a8a6d169292ff
in Swift 2.0 (error)
, so I change my code as follows.
let url = NSURL(string:"http://dl-8.one2up.com/onetwo/content/2015/6/15/9c3b51249fbbe20ca9d841401e276d97.php")
let allContactsData = NSData(contentsOfURL:url!)
do{
var allContacts : AnyObject! = try NSJSONSerialization.JSONObjectWithData(allContactsData!, options: NSJSONReadingOptions())
}catch{
print(error)
}
if let json = allContacts as? Array<AnyObject> {
print(json)
for index in 0...json.count-1 {
let contact : AnyObject? = json[index]
let collection = contact! as! Dictionary<String, AnyObject>
let name : AnyObject? = collection["AnimeName"]
let cont : AnyObject? = collection["Episodes"]
names.append(name as! String)
episodes.append(cont as! String)
}
}
print(names)
print(episodes)
But that doesn't work.
if let json = allContacts as? Array< AnyObject >
error : Use of unresolved identifier 'allContacts'
Your allContacts variable is created in the do block, therefore its scope is limited to the do block, and cannot be accessed outside of that block. If you want it to be accessible outside the block, declare it outside of the block, but then continue to assign it inside the block. IE:
let allContactsData = NSData(contentsOfURL:url!)
var allContacts:AnyObject
do{
allContacts = try NSJSONSerialization.JSONObjectWithData(allContactsData!, options: NSJSONReadingOptions())
}catch{
print(error)
}
do{
var allContacts = try NSJSONSerialization.JSONObjectWithData(allContactsData!, options: NSJSONReadingOptions()) as! [Dictionary<String, AnyObject>]
for contact in allContacts {
let name : AnyObject? = contact["AnimeName"]
let cont : AnyObject? = contact["Episodes"]
names.append(name as! String)
episodes.append(cont as! String)
}
}catch{
print(error)
}

Swift NSUserDefaults setObject for Array

i need to save with NSUserDefaults an array that i get from jSON, the problem is it save only the first string and not all the array. So if the array is like NewYork,London,Rome .. it save only NewYork. I use it for a picker view.
This is the code:
EDIT
For save the Array from jSON:
if let jsonData = NSJSONSerialization.JSONObjectWithData(urlData!, options: nil, error: &error) as? [String:AnyObject] { // dictionary
if let locationsArray = jsonData["locations"] as? [[String:AnyObject]] { // array of dictionaries
for locationDictionary in locationsArray { // we loop in the array of dictionaries
if let location = locationDictionary["location_name"] as? String { // finally, access the dictionary like you were trying to do
// println(location)
var locationSave: Void = save.setObject(location, forKey: "Location")
}
}
}
}
}
and for request the Array:
var Location = save.objectForKey("Location")!
var pickerviewFields = Location
return pickerviewFields.count
Thanks in advance!
You can only save an NSArray, if the Array is a Swift Array, you will need to convert it. Also, NSArray and NSDictionary objects, their contents must be property list objects.
Here's how you would convert the Array:
var MyArray = ["a", "b", "c"]
var MyNSArray: NSArray
MyNSArray = MyArray as NSArray
println("\(MyNSArray)")
Prints: (a,b,c)
I have a small example with some sample JSON:
var myJSONString: NSString = "{ \"locations\" : [ { \"location_name\" : \"A\" }, { \"location_name\" : \"B\" }, { \"location_name\" : \"C\" }, { \"location_name\" : \"D\" } ] }"
var urlData: NSData? = NSData()
var error: NSError?
var save = NSUserDefaults.standardUserDefaults()
urlData = myJSONString.dataUsingEncoding(NSUTF8StringEncoding)
if let jsonData = NSJSONSerialization.JSONObjectWithData(urlData!, options: nil, error: &error) as? NSDictionary { // dictionary
if let locationsArray = jsonData["locations"] as? NSArray { // array of dictionaries
for locationDictionary in locationsArray { // we loop in the array of dictionaries
if let location = locationDictionary["location_name"] as? NSString {
println(location)
}
}
NSUserDefaults.standardUserDefaults().setObject(locationsArray, forKey: "locationArray")
}
}
println(save.dictionaryRepresentation())
You can try this:
Writing
let locationArray = ["London", "NewYork", "Rome"]
let locationData = NSKeyedArchiver.archivedDataWithRootObject(locationArray)
NSUserDefaults.standardUserDefaults().setObject(locationData, forKey: "Location")
NSUserDefaults.standardUserDefaults().synchronize()
Reading
let locationData = NSUserDefaults.standardUserDefaults().objectForKey("Location") as? NSData
if let locationData = locationData {
let locationArray = NSKeyedUnarchiver.unarchiveObjectWithData(locationData) as? [String]
if let locationArray = locationArray {
println(locationArray)
}
}

Resources