Need help in JSON parsing - json

I am getting data from API and I need to filter the array of dictionary based upon "total_price" tag, now the condition is I want only those flights whose price is between "35.0" to "55.0"
{
airline = 9W;
"available_seats" = "<null>";
bags = (
);
currency = USD;
destination = 38551;
origin = 39232;
"price_details" = {
};
"rate_plan_code" = WIP;
routes = (
);
taxes = "17.51";
"total_price" = "31.7";
}
As the total_price tag is coming as string I am not sure how to filter it using predicate etc. I need to filter the json response itself, no models were created for this API response.

Since you want to filter on prices I assume you get an array and I have further assumed in my code this array is inside a dictionary with the key "flights" so you need to change this key to whatever you have
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
if let flights = json["flights"] as? [[String: Any]] {
let filtered = flights.filter {
if let str = $0["total_price"] as? String, let price = Double(str) {
return price >= 35.0 && price <= 55.0
}
return false
}
print(filtered.count) // replace with more meaningful code :)
}
}
} catch {
print("Decode failed: \(error)")
}

Related

How to Display data from JSON in Alphabetical Sections Swift?

I've been using JSONParsing to display my data when you search for a term. Now I want to list out all of those terms in an alphabetized list. But am having trouble getting the code to work correctly. I've replicated some code from someone else that was having the same problem and got that to work but I'm having trouble implementing my own code.
I currently am parsing my JSON with this code:
func parseJSONSignDictionary() {
if let url = Bundle.main.url(forResource: "csvjson", withExtension: "json") {
do {
let date = Date()
let data = try Data(contentsOf: url)
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] {
(json["results"] as? [[String:Any]])?.forEach { j in
if let name = j["identifier"] as? String, let id = j["id"] as? Int {
let sign = Signs(name: name, number: id)
signsArray.append(sign)
}
}
}
print("Took", Date().timeIntervalSince(date))
} catch {
print(error.localizedDescription)
}
}
}
Edit to add some more code, this is my Signs class, which would replace the Restaurant Array/Class:
class Signs: NSObject, Decodable, NSCoding {
private var _signName: String!
private var _signNumber: Int!
var signName: String {
return _signName
}
var signNumber: Int {
return _signNumber
}
func encode(with aCoder: NSCoder) {
aCoder.encode(signName, forKey: "signNameKey")
}
required init?(coder aDecoder: NSCoder) {
print("Trying to turn Data into Sign")
self._signName = aDecoder.decodeObject(forKey: "signNameKey") as? String
}
init(name: String, number: Int) {
self._signName = name
self._signNumber = number
}
}
The code from another StackOverflow that I'm trying to use is from here. question:Display data from JSON in alphabetical sections in Table View in Swift
func makeDataSource(names:[String:[AnyObject]]) {
var dict = [String:[Restaurant]]()
let letters = NSCharacterSet.letters
for (_,value) in names {
//Iterating Restaurants
for resObj in value {
if let restaurantName = resObj["name"] as? String {
let restaurant = Restaurant(name: restaurantName)
var key = String(describing: restaurant.name.first!)
//To check whether key is alphabet or not
key = isKeyCharacter(key: key, letters: letters) ? key : "#"
if let keyValue = dict[key] {
//Already value exists for that key
var filtered = keyValue
filtered.append(restaurant)
//Sorting of restaurant names alphabetically
//filtered = filtered.sorted(by: {$0.0.name < $0.1.name})
dict[key] = filtered
} else {
let filtered = [restaurant]
dict[key] = filtered
}
}
}
}
//To sort the key header values
self.dataArray = Array(dict).sorted(by: { $0.0 < $1.0 })
//Logic to just shift the # category to bottom
let temp = self.dataArray[0]
self.dataArray.removeFirst()
self.dataArray.append(temp)
self.indexTitles = Array(dict.keys.sorted(by: <))
let tempIndex = self.indexTitles[0]
self.indexTitles.removeFirst()
self.indexTitles.append(tempIndex)
}
I have my own array that would replace Restaurant, called Signs.
if let restaurantName = resObj["name"] as? String {
I'm also wondering where this "name" is being pulled from? Is it the array/model which has the var name?
I'm not sure since I have a way to access the JSON data with my own function if I even need to try to use the getdata() function.
I just wanna understand what I'm missing, and how to do it on my own to get the code to work properly.

How do I access a specific value in this dictionary of JSON using Swift?

I am trying to get the total Wins from this API (Tracker Network API) and I have gotten the key and it displays the key and value like so.
The code is below and I am also able to get the number of wins (Integer) along with these values(Titles). However, I cannot figure out how to just get the "Wins" number without having all the other numbers printing out too.
I have tried
print(statsArray[8])
totalWins = statsArray[8]
//["value": 4350, "key": Wins]
print(totalWins.values)
//[Wins, 4350]
but it does not print it how I would like it to print. I would like it to print out as just the number so that I can then load that number into a UILabel.
What I am asking, is how do I print the "Wins" (integer) amount only and not the other 11 json outputs? I just want one of the numbers.
let epicName = "Ninja"
let formattedName = epicName.replacingOccurrences(of: " ", with: "%20")
let platform = "pc"
//pc, xbl, psn
let fortniteChallengesURL3 = URL(string: "https://api.fortnitetracker.com/v1/profile/\(platform)/\(formattedName)")
if let unwrappedURL = fortniteChallengesURL3 {
var request = URLRequest(url: unwrappedURL)
request.addValue("MyKey", forHTTPHeaderField: "TRN-Api-Key")
let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data) as! [String:Any]
//print(json)
for (key, value) in json {
if (key == "lifeTimeStats") {
if let statsArray:[ [String : Any] ] = value as? [ [String : Any] ] {
//accessing the 8th but I am getting the output wrong
/*let firstKey = Array( (value as? [ [String : Any] ])!)[8]
*/
print(statsArray[8])
let totalWins = statsArray[8]
//["value": 4350, "key": Wins]
print(totalWins.values)
//[Wins, 4350]
for dict in statsArray {
for (key, value) in dict {
if (key == "key") {
//print ( "\(firstKey.values)")
print ( "keys are \(value)")
}
/*if (key == "value") {
print ( "value are \(value)")
}*/
}
}
}
}
}
} catch let error as NSError {
print(error.localizedDescription)
DispatchQueue.main.asyncAfter(deadline: .now() ) {
}
}
}
}
dataTask.resume()
}
TotalWins is a dictionary with two items and you can access any item value in a dictionary by its key, so try this:
print(totalWins["value"])
When you iterate over each item in the array of dictionaries you can access the key and the value fields directly like so:
for dic in statsArray {
let title = dic["key"]
let value = dic["value"] // You can use this as the value for the label
}
If you want to only access the total wins data, you could do:
let totalWinsValues = totalWins["value"]
You will want to look into creating a data model in the form of a struct of a class, and implementing the Codable protocol to make things easier and cleaner.

How to turn my JSON result into an array or object

I have been searching every where, but cannot get to the right answer. I receive a Json result with the following structure
{
result = {
"2ab5a003-0120-4c01-80f2-a237dcf4ba14" = {
icon = garden;
id = "2ab5a003-0120-4c01-80f2-a237dcf4ba14";
index = 1;
name = "Tafel hoek";
parent = "855113f1-f488-4223-b675-2f01270f573e";
};
"2afd6093-ca6d-4e52-aaca-336ab76ea454" = {
icon = default;
id = "2afd6093-ca6d-4e52-aaca-336ab76ea454";
index = 11;
name = Badkamer;
parent = "9919ee1e-ffbc-480b-bc4b-77fb047e9e68";
};
};
status = 200;
}
Because I don't know the 1st key in the result I am lost to get the separate items. Is there any one who can help me ? Thanks in advance
my code is:
{ print("Error: ")
print(error!)
} else { // no error
if let urlContent = data { // 3
do { // 4
let json = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
print(json)
} catch {
print("JSON processing failed")
} // end 4 do
} // end 3 let urlContent
} // end 2 if error}
Since you have the dictionary for key result, you can enumerate it as usual:
if let result = json["result"] as? [String:[String:Any]] {
for (key, value) in result {
let name = value["name"] as! String
let index = value["index"] as! Int
print (key, name, index)
}
}
Can you post your code ,i think that is not a valid json format and tell me where you are struggling to parse.ignore that key and try as usual

Get JSON Element in Swift 3

Please excuse me if this is a simple question, but I am stuck. I have tried to read everything I can to work it out myself.
I am trying to extract a URL from JSON data, I get the JSON data fine and I can print it to the console, however I can't work out how to access the URL for the audio file.
This is the code I use to get the JSON:
let session = URLSession.shared
_ = session.dataTask(with: request, completionHandler: { data, response, error in
if let response = response,
let data = data,
let jsonData = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) {
if let dictionary = jsonData as? [String: Any] {
if let prounce = dictionary["pronunciations"] as? [String: Any]{
if let audioPath = prounce["audioFile"] as? String {
print(audioPath)
}
}
}
print(response)
print(jsonData)
} else {
print(error)
print(NSString.init(data: data!, encoding: String.Encoding.utf8.rawValue))
}
}).resume()
The output I get is:
metadata = {
provider = "Oxford University Press";
};
results = (
{
id = maladroit;
language = en;
lexicalEntries = (
{
entries = (
{
etymologies = (
"late 17th century: French"
);
grammaticalFeatures = (
{
text = Positive;
type = Degree;
}
);
senses = (
{
definitions = (
"inefficient or inept; clumsy:"
);
examples = (
{
text = "both men are unhappy about the maladroit way the matter has been handled";
}
);
id = "m_en_gb0494140.001";
}
);
}
);
language = en;
lexicalCategory = Adjective;
pronunciations = (
{
audioFile = "http://audio.oxforddictionaries.com/en/mp3/maladroit_gb_1.mp3";
dialects = (
"British English"
);
phoneticNotation = IPA;
phoneticSpelling = "\U02ccmal\U0259\U02c8dr\U0254\U026at";
}
);
text = maladroit;
}
);
type = headword;
word = maladroit;
}
);
}
I want to get the URL called audioFile in the pronunciations. Any help is much appreciated.
If my guess is right, your output shown above lacks opening brace { at the top of the output.
(I'm also assuming the output is taken from your print(jsonData).)
Your jsonData is a Dictionary containing two values:
A dictionary value for "metadata"
An array value for "results"
So, you cannot retrieve a value for "pronunciations" directly from jsonData (or dictionary).
You may need to:
Retrieve the value for "results" from jsonData, it's an Array
Choose one element from the "results", it's a Dictionary
Retrieve the value for "lexicalEntries" from the result, it's an Array
Choose one element from the "lexicalEntries", it's a Dictionary
Retrieve the value for "pronunciations" from the lexicalEntry, it's an Array
Choose one element from the "pronunciations", it's a Dictionary
Here, you can access the values in each pronunciation Dictionary. In code, you need to do something like this:
if
let dictionary = jsonData as? [String: Any],
let results = dictionary["results"] as? [[String: Any]],
//You need to choose one from "results"
!results.isEmpty, case let result = results[0],
let lexicalEntries = result["lexicalEntries"] as? [[String: Any]],
//You need to choose one from "lexicalEntries"
!lexicalEntries.isEmpty, case let lexicalEntry = lexicalEntries[0],
let pronunciations = lexicalEntry["pronunciations"] as? [[String: Any]],
//You need to choose one from "lexicalEntries"
!pronunciations.isEmpty, case let pronunciation = pronunciations[0]
{
//Here you can use `pronunciation` as a Dictionary containing "audioFile" and some others...
if let audioPath = pronunciation["audioFile"] as? String {
print(audioPath)
}
}
(You can use let result = results.first instead of !results.isEmpty, case let result = results[0], if you always use the first element for arrays. Other two lines starting from !...isEmpty, case let... as well.)
You need to dig into the target element from the outermost element step by step.

How to check if a key is present in NSArray populated with json data in SWIFT?

i am trying to parse this json response.
account = (
{
accountName = "Complete Access";
accountNumber = "062005 1709 5888";
available = "226.76";
balance = "246.76";
}
);
var account : NSArray = jsonResult.valueForKey("account") as NSArray
Now, this array contains all value for key “account”. Inside this array how we can check if it contains the key “balance” or not.I tried to check it as below :
if account .containsObject(account(idx).valueForKey(“balance"))
{
transactions.balance = account(idx).valueForKey(“balance”) as? String
}
But, it never got inside the if condition. Please sugget the correct way to achieve this.
something like this may help on you:
let keyAccount: String = "account"
let keyBalance: String = "balance"
var jsonResult : Dictionary<String, AnyObject> = ["account":[["accountName":"Complete Access", "accountNumber":"062005 1709 5888", "available":"226.76", "balance":"246.76"]]]
var account : AnyObject? = jsonResult[keyAccount]
if let accountArray: Array<AnyObject>? = account as? Array {
if accountArray!.count > 0 {
if let accountDictionary: Dictionary<String, String>? = accountArray![0] as? Dictionary {
if let balanceValue: String? = accountDictionary![keyBalance] {
println("\(balanceValue)")
}
}
}
}