How to get one value from a Codable struct with multiple values? - ios

I have a large JSON response and inside
{
"availabilityResultList": [
{
"availabilityRouteList": [
{
"availabilityByDateList": [
{
"originDestinationOptionList": [
there are 3 separate
"originDestinationOptionList": [
{
"fareComponentGroupList":[...]
},
{
"fareComponentGroupList":[...]
},
{
"fareComponentGroupList":[...]
},
],
I can access the values in the first 'fareComponentGroupList' with Codables
as
root.availabilityResultList.first?.availabilityRouteList.first?.availabilityByDateList.first?.originDestinationOptionList.first?.fareComponentGroupList.first?.xxx
How do I access values the second and third fareComponentGroupList ?
(I am sorry about these silly questions but I am new with swift Codables)

Since originDestinationOptionList returns an array of dictionary, just fetch it from there by index.
let originDestinationOptionList = root.availabilityResultList.first?.availabilityRouteList.first?.availabilityByDateList.first?.originDestinationOptionList
let firstobject = originDestinationOptionList[0]["fareComponentGroupList"]
let secondObject = originDestinationOptionList[1]["fareComponentGroupList"]
let firstObjectsFirstItem = firstObject[0]
If the above gives error, this works ( Swift 5)
let originDestinationOptionList = root.availabilityResultList.first?.availabilityRouteList.first?.availabilityByDateList.first?.originDestinationOptionList
let firstobject = originDestinationOptionList[0].fareComponentGroupList.first
let firstObjectsFirstItem = firstObject?. (add the remaining part)

Related

How would this JSON be represented with classes?

I have a JSON object that gets loaded as [String: Any]. I want to break down each part and turn the "Any" into an actual class. Here's one section of the JSON that I'm starting with:
"objects": {
"Yellow Fruits" = {
name = "Bananas";
numbers = (
0,
1
);
};
"Red Fruits" = {
name = "Strawberries";
numbers = (
2,
4,
5,
14,
15,
16,
17
);
};
}
I've tried representing these "fruits" with the following class:
class Fruit {
var name: String?
var officeIndicies: [Int]?
}
When I try to load this with
guard let fruits = json["objects"] as? [String: Fruit]
it seems that the Fruit class does not accurately represent what is in the json.
Is there something obvious I'm missing?

swift parse json as per maintaining order

Suppose i have json string in which there is a json array called data.
The array holds json object of user profile data for example name,age,gender etc.
Now want to parse that json object as per order, for example if the object is
{
"name": "sample name",
"age": "30",
"gender": "male"
}
i want to parse the list as ordered like name,age,gender but with ios,when i convert the json object as dictionary , the order is changed,i know dictionary is not ordered so what is the the alternative to achieve this?
its a third party api so i dont have any hand on it,we have done it in android with linked hash map,but really stuck in swift , the last thing i would want to do is parse with regular expression.
im parsing the json in following way :
var rootData = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
if let val = fromList["data"] {
let dataNode = val as! [[String:Any]]
for row in dataNode {
for (key,keyVal) in row {
//here the key is not in order.because when we cast it as dictionary the order gets changed.
}
}
For android we have achieved to do this with following function :
public ArrayList<LinkedHashMap<String, Object>> parseJsonArrayList(String odata, String arrayName) {
ArrayList<LinkedHashMap<String, Object>> mylist = new ArrayList<>();
try {
JSONObject e = new JSONObject(odata);
JSONArray data = e.getJSONArray(arrayName);
for(int i = 0; i < data.length(); ++i) {
JSONObject v = data.getJSONObject(i);
LinkedHashMap<String, Object> map = new LinkedHashMap<>(100, 0.75f, false);
Iterator keys = v.keys();
while(keys.hasNext()) {
String key = String.valueOf(keys.next());
//gph.log("debug4", key);
map.put(key, v.getString(key));
//gph.log("debug4", v.getString(key));
}
mylist.add(map);
}
} catch (JSONException var10) {
var10.printStackTrace();
}
return mylist;
}
Don’t try to order the dictionary. Instead create an array of the keys in the order you desire:
let keys = [“name”, “age”, “gender”]
Then access the dictionary with them:
for key in keys {
let value = dict[key]
// Present the value.
}
That will ensure the order you expect.
As you mentioned you cannot get the ordered data in Dictionary. If possible you can add the "order" key in your JSON like
[
{
"name": "sample name",
"order": 1
},
{
"age": "30",
"order": 1
},
{
"gender": "",
"male": "",
"order": 1
}
]
so that based on the order key you can do the sorting.

Taking out array from dictionary in swift 3

Hi I am trying to populate a view using the response obtained from service but not able to fetch the exact value out of the whole response ,
[
["product_id": PRO161519,
"name": clothes,
"brand_name": Levis,
"discountprice": 0,
"images": <__NSArrayM 0x6000002541c0>(
{
image = "HTTP://i.vinove.com/dnn/backend/uploads/954tshirt_PNG5434.png";
}
)
"category": Accessories,
"price": 23.00
]
]
ProductList-Model
import UIKit
import SpeedLog
let KImages = "images"
let KListImage = "image"
struct ProductList{
var images = ""
var itemArray = [String]()
func bindProductListDataToPopulateView(_ response:[[String:Any]])->[ProductList]{
SpeedLog.print("response value as result",response)
for items in response{
print("items values",items)
}
print("item array",itemArray)
return []
}
}
response value as result
[["image":
item Values
["image":
Kindly help me to get the values images here.
You have to use like this :
for product in products {
if let productImages = product["images"], let images = productImages as? NSArray {
for image in images {
if let image = image as? [String: String] {
print(image["image"])
}
}
}
}
More than likely that JSON response you posted will eventually find its way to you in the form of a key-value Dictionary. You then use a "key" from the JSON you posted to extract the key's corresponding "value". In the snippet you posted, the keys would be the values on the left of the colon (e.g. "product_id", "name", etc).
Now, lets say your dictionary of key-values was called "jsonDictionary". You then would extract the values like so:
let productId = jsonDictionary["product_id"]
let name = jsonDictionary["name"]
If, however, you don't have logic to deserialize that raw JSON data (that you posted in your question) into a Dictionary, then you'll have to start there instead.

Reorder array of Dictionary By swift

I'm working on ios app by swift!
An i need to display the data from the array of dictionary order by the price value.
How can i reorder this array
(
{
price = 269600;
userid = "facebook:851661711521620";
},
{
price = 294600;
userid = "facebook:851661711521620";
},
{
price = 1345600;
userid = "facebook:851661711521620";
},
{
price = 287600;
userid = "facebook:851661711521620";
},
{
price = 1344600;
userid = "facebook:851661711521620";
},
{
price = 1343600;
userid = "facebook:851661711521620";
},
{
price = 1333600;
userid = "facebook:851661711521620";
},
{
price = 1332600;
userid = "facebook:851661711521620";
},
{
price = 1322600;
userid = "facebook:851661711521620";
},
{
price = 322600;
userid = "facebook:851661711521620";
},
{
price = 302600;
userid = "facebook:851661711521620";
},
{
price = 300600;
userid = "facebook:851661711521620";
},
{
price = 291600;
userid = "facebook:851661711521620";
},
{
price = 282600;
userid = "facebook:851661711521620";
},
{
price = 299600;
userid = "facebook:851661711521620";
}
)
to be ordered by price from The highest to The lowest?
i need to display the data to be like this
Any ideas how can i do it Thanks!
Thanks!
Edited add some actual code.
self.currentBidDict = snapshot.value["current_bid_id"] as! NSDictionary
for(var i = 0;i <= self.currentBidDict.count - 1;i++){
self.currentBidDictReOrder.insertObject(self.currentBidDict.allValues[i], atIndex: 0)
println(self.currentBidDictReOrder)
}
Then after i printIn i got array above in the question.
There is a function, sort, that takes any sequence, and returns a sorted array. Since dictionaries are sequences of (key,value) pairs, you can pass the dictionary in to sort.
If what you pass in isn’t naturally sortable (i.e. the elements of the sequence are Comparable, which dictionaries aren’t), you need to also supply a closure telling sort how to order the elements. In your case, you want that closure to compare the value for a specific key in the dictionaries.
Finally, you want to sort by a value, but looking up a key in a dictionary returns an optional (because the key might not be there). But, this is fine! Because optionals have a < operator that works, so long as what the optional contains is comparable. Except, it looks like you’ve got a dictionary of Any or AnyObject (because you have both strings and integers in there), so you’ll have to covert them to something you can compare.
Put it all together and:
sorted(dict) { ($0["price"] as? Int) > ($1["price"] as? Int) }
You might want to tweak that as? a bit depending on what your dictionary actually contains. Also, I’d strongly suggest looking at creating a more strongly-typed struct and populating that with your data, rather than leaving it in dictionary form like this.
You can use the sort function in the following way:
var dict = [[
"price" : 1111,
"userid" : "facebook:851661711521620"
],
[
"price" : 12222,
"userid" : "facebook:851661711521620"
],
[
"price" : 144444,
"userid" : "facebook:851661711521620"
]]
// sort by price
dict.sort {
x, y in
let item1 = x["price"] as! Int
let item2 = y["price"] as! Int
return item1 > item2
}
And the output should be like this:
[[price: 144444, userid: facebook:851661711521620], [price: 12222, userid: facebook:851661711521620], [price: 1111, userid: facebook:851661711521620]]
I hope this help you.

Parsing JSON Response with Alamofire in Swift

When using the Alamofire Framework, my responses don't seem to be getting parsed correctly. The JSON response I get has some keys that appear to not be strings, and I don't know how to reference them/get their values.
Here is the part of my code that makes the call:
var url = "http://api.sandbox.amadeus.com/v1.2/flights/low-fare-search"
var params = ["origin": "IST",
"destination":"BOS",
"departure_date":"2014-10-15",
"number_of_results": 1,
"apikey": KEY]
Alamofire.request(.GET, url, parameters: params)
.responseJSON { (_, _, json, _) in
println(json)
}
}
And here is the first section printout when that function is called
Optional({
currency = USD;
results = ({
fare = {
"price_per_adult" = {
tax = "245.43";
"total_fare" = "721.43";
};
restrictions = {
"change_penalties" = 1;
refundable = 0;
};
"total_price" = "721.43";
};
...
});
});
You'll notice that results is not "results", but "price_per_adult" is the correct format. Is there some step I'm missing? When I cast it to NSDictionary it doesn't do anything to help the key format either.
I also tried the same endpoint in javascript and ruby, and both came back without problem, so I'm fairly confident that it is not the API that is causing problems.
Those keys are still Strings, that's just how Dictionarys are printlnd. It looks like it will surround the String in quotes when printing it only if it contains non-alphanumeric characters (_ in this case). You can test this by manually creating a Dictionary similar to the one you're getting back from your API request and then printing it:
let test = [
"currency": "USD",
"results": [
[
"fare": [
"price_per_adult": [
"tax": "245.43",
"total_fare": "721.43"
],
"restrictions": [
"change_penalties": 1,
"refundable": 0
],
"total_price": "721.43"
]
]
]
]
println(test)
Outputs:
{
currency = USD;
results = (
{
fare = {
"price_per_adult" = {
tax = "245.43";
"total_fare" = "721.43";
};
restrictions = {
"change_penalties" = 1;
refundable = 0;
};
"total_price" = "721.43";
};
}
);
}

Resources