Day Summary from JSON and swift - json

I am abel to get the current and hourly weather data and based on the following criteria:
viewController:
let dailyWeather = weatherForecast.weekly[0]
let hourlyWeather = weatherForecast.hourly[hour + 4]
let weeklyWeather = weatherForecast.weekly
self.hourlySummaryLabel.text = hourlyWeather.hourlySummary
self.tomorrowSummary.text = dailyWeather.summary
forecast.swift:
struct Forecast {
var currentWeather: CurrentWeather?
var weekly: [DailyWeather] = []
var hourly: [HourlyWeather] = []
init(weatherDictionary: [String: AnyObject]){
if let currentWeatherDictionary = weatherDictionary["currently"] as? [String: AnyObject] {
currentWeather = CurrentWeather(weatherDictionary: currentWeatherDictionary)
}
if let weeklyWeatherArray = weatherDictionary["daily"]?["data"] as? [[String: AnyObject]] {
for dailyWeather in weeklyWeatherArray {
let daily = DailyWeather(dailyWeatherDictionary: dailyWeather)
weekly.append(daily)
}
}
if let hourlyWeatherArray = weatherDictionary["hourly"]?["data"] as? [[String:AnyObject]] {
for hourlyWeather in hourlyWeatherArray {
let hour = HourlyWeather(dailyWeatherDictionary: hourlyWeather)
hourly.append(hour)
}
}
}
}
however, i need to get the full day summary from the following json:
units = si;
}, "hourly": {
data = (
{
{
apparentTemperature = "33.61";
cloudCover = 0;
dewPoint = "12.77";
humidity = "0.27";
icon = "clear-day";
ozone = "279.14";
precipIntensity = 0;
precipProbability = 0;
pressure = "1004.85";
summary = Clear;
temperature = "34.66";
time = 1463464800;
windBearing = 4;
windSpeed = "2.48";
}
);
icon = wind;
summary = "Breezy until this evening."; -----> Need This Summary
is there any way to do it?

Related

Swift JSON Data

I received the JSON data as shown below, I want to get the "player_name" & "player_country" from this data. How do I get this?**enter image description here
In case, the image does not load, please refer the below output:
["team_key": 2611, "team_name": Leicester, "team_badge": https://apiv2.apifootball.com/badges/2611_leicester.png, "players": <__NSArrayI 0x600003331e00>(
{
"player_age" = 33;
"player_country" = Denmark;
"player_goals" = 0;
"player_key" = 140150332;
"player_match_played" = 30;
"player_name" = "Schmeichel Kasper";
"player_number" = 1;
"player_red_cards" = 0;
"player_type" = Goalkeepers;
"player_yellow_cards" = 2;
},
{
"player_age" = 23;
"player_country" = England;
"player_goals" = 3;
"player_key" = 2242127097;
"player_match_played" = 24;
"player_name" = "Chilwell Benjamin";
"player_number" = 3;
"player_red_cards" = 0;
"player_type" = Defenders;
"player_yellow_cards" = 2;
},
{.....}
I tried the following to get required data from this:
var mainArray = [[String: Any]]()
var tryArray = [[String]]()
for i in jsonArray {
if i["team_key"] as! String == teamID {
self.mainArray.append(i)
}
}
for i in self.mainArray {
self.tryArray.append(i["player_name"] as! [String])
}
I got this error with the above code:
Fatal error: Unexpectedly found nil while unwrapping an Optional value
let playerArray:NSDictionary = json as! NSDictionary
for var player in playerArray {
self.tryArray.append(player.objectForKey("player_name") as! String)
self.tryArray.append(player.objectForKey("player_country") as! String)
}
Thank you all for your response. I have tried this and it works.
var mainArray = NSArray()
var tryArray = [[String: Any]]()
for i in jsonArray {
if i["team_key"] as! String == teamID {
self.mainArray = i["players"] as! NSArray
}
}
for i in self.mainArray {
tryArray.append(i as! [String : Any])
}
What I did was I made mainArray as NSArray instead of [[String: Any]] and then copy it to tryArray which is of actually [[String: Any]] type and used tryArray for my work.
Thanks.

Array in Array Swift 4 Json

["?xml": {
"#encoding" = "utf-8";
"#version" = "1.0";
}, "root": {
"#id" = 1;
date = "11/25/2018";
message = "";
station = (
{
abbr = 24TH;
etd = (
{
abbreviation = ANTC;
destination = Antioch;
estimate = (
{
bikeflag = 1;
color = YELLOW;
delay = 86;
direction = North;
hexcolor = "#ffff33";
length = 10;
minutes = 4;
platform = 2;
},
{
bikeflag = 1;
color = YELLOW;
delay = 0;
direction = North;
hexcolor = "#ffff33";
length = 10;
minutes = 23;
platform = 2;
},
{
bikeflag = 1;
color = YELLOW;
delay = 0;
direction = North;
hexcolor = "#ffff33";
length = 10;
minutes = 43;
platform = 2;
}
);
limited = 0;
},
{
abbreviation = DALY;
destination = "Daly City";
estimate = (
{
bikeflag = 1;
color = BLUE;
delay = 214;
direction = South;
hexcolor = "#0099cc";
length = 9;
minutes = 11;
platform = 1;
},
{
bikeflag = 1;
color = BLUE;
delay = 0;
direction = South;
hexcolor = "#0099cc";
length = 9;
minutes = 27;
platform = 1;
},
{
bikeflag = 1;
color = BLUE;
delay = 0;
direction = South;
hexcolor = "#0099cc";
length = 9;
minutes = 47;
platform = 1;
}
);
limited = 0;
},
{
abbreviation = DUBL;
destination = "Dublin/Pleasanton";
estimate = (
{
bikeflag = 1;
color = BLUE;
delay = 0;
direction = North;
hexcolor = "#0099cc";
length = 9;
minutes = 10;
platform = 2;
},
{
bikeflag = 1;
color = BLUE;
delay = 0;
direction = North;
hexcolor = "#0099cc";
length = 9;
minutes = 30;
platform = 2;
},
{
bikeflag = 1;
color = BLUE;
delay = 0;
direction = North;
hexcolor = "#0099cc";
length = 9;
minutes = 50;
platform = 2;
}
);
limited = 0;
},
{
abbreviation = MLBR;
destination = "SFO/Millbrae";
estimate = (
{
bikeflag = 1;
color = YELLOW;
delay = 245;
direction = South;
hexcolor = "#ffff33";
length = 10;
minutes = 17;
platform = 1;
},
{
bikeflag = 1;
color = YELLOW;
delay = 254;
direction = South;
hexcolor = "#ffff33";
length = 10;
minutes = 38;
platform = 1;
},
{
bikeflag = 1;
color = YELLOW;
delay = 0;
direction = South;
hexcolor = "#ffff33";
length = 10;
minutes = 53;
platform = 1;
}
);
limited = 0;
}
);
name = "24th St. Mission";
}
);
time = "05:28:01 PM PST";
uri = {
"#cdata-section" = "http://api.bart.gov/api/etd.aspx?cmd=etd&orig=24TH&json=y";
};
}]
Want to get abbr, abbreviation, minutes in three separate arrays. So the root is a separate element as in, key1 = xml and key2 = root.
this is what I have. I am getting till estimates array but not able to get the values like I mentioned before.
static func singleRoute(_ station: String?, completionHandler: #escaping (SingleRouteModel?) -> Void) {
let routeURL = URL(string: "http://api.bart.gov/api/etd.aspx?cmd=etd&orig=\(station ?? "12TH")&key=MW9S-E7SL-26DU-VV8V&json=y")
var routeModel = SingleRouteModel()
URLSession.shared.dataTask(with: routeURL!) { (data, response, error) in
if error == nil {
do {
guard let todo = try JSONSerialization.jsonObject(with: data!, options:.mutableContainers)
as? [String: Any] else {
print("error trying to convert data to JSON")
return
}
print("todo = \(todo)")
let root = todo["root"] as? [String: Any]
let station = root?["station"] as? [[String: Any]]
var etd: [[String : Any]]?
var estimate: Any?
for (_, value) in (station?.enumerated())! {
etd = value["etd"] as? [[String: Any]]
}
var estimates: [String: Any]? = [:]
if let etd = etd {
for (key, value) in etd.enumerated() {
estimates?["\(key)"] = value
}
} else {
completionHandler(nil)
}
if let estimate = estimates {
for (k, v) in estimate {
print(v)
}
}
completionHandler(routeModel)
} catch {
print("error trying to convert data to JSON")
return
}
} else {
print("no data")
}
}.resume()
}
Here's the code in Playground form:
import Foundation
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
struct Estimate: Codable {
let minutes: String
}
struct ETD: Codable {
let abbreviation: String
let estimate: [Estimate]
}
struct Station: Codable {
let abbr: String
let etd: [ETD]
}
struct Root: Codable {
let station: [Station]
}
struct SingleRouteModel: Codable {
let root: Root
}
func singleRoute(_ station: String?, completionHandler: #escaping (SingleRouteModel?) -> Void) {
let routeURL = URL(string: "http://api.bart.gov/api/etd.aspx?cmd=etd&orig=\(station ?? "12TH")&key=MW9S-E7SL-26DU-VV8V&json=y")
URLSession.shared.dataTask(with: routeURL!) { (data, response, error) in
if let data = data {
let model = try? JSONDecoder().decode(SingleRouteModel.self, from: data)
completionHandler(model)
}
else {
completionHandler(nil)
}
}.resume()
}
singleRoute(nil, completionHandler: { model in
guard let model = model else { print("failed"); return }
let abbrs = model.root.station
.map { $0.abbr }
let abbreviations = model.root.station
.flatMap { $0.etd }
.flatMap { $0.abbreviation }
let minutes = model.root.station
.flatMap { $0.etd }
.flatMap { $0.estimate }
.map { $0.minutes }
print("abbrs:", abbrs)
print("abbreviations:", abbreviations)
print("minutes:", minutes)
})

Getting All the values of this output json

I want to extract the names of these coffes this is an extract of my output because i have like 1000 names, and i want to take them all automatically :
results = (
{
geometry = {
location = {
lat = "-33.3979227";
lng = "-70.58503859999999";
};
viewport = {
northeast = {
lat = "-33.39783990000001";
lng = "-70.58502229999999";
};
southwest = {
lat = "-33.39795669999999";
lng = "-70.58507830000001";
};
};
};
id = 46354da06de96a36c5c44a5fa05a10f8f83f8edd;
name = "Hotel Bidasoa";
"opening_hours" = {
"open_now" = 1;
"weekday_text" = (
);
};
}
);
"place_id" = ChIJ4dfUCC7PYpYRRDkSNifrfBE;
rating = "4.7";
scope = GOOGLE;
types = (
cafe,
lodging,
food,
store,
"point_of_interest",
establishment
);
vicinity = "Avenida Vitacura 4873, Santiago, Santiago";
},
{
geometry = {
location = {
lat = "-33.37900460000001";
lng = "-70.55533029999999";
};
viewport = {
northeast = {
lat = "-33.37897230000002";
lng = "-70.5553148";
};
southwest = {
lat = "-33.37910149999999";
lng = "-70.55537679999999";
};
};
};
id = c451d2146b7a065fa1afd0ffa39353a4b1cae178;
name = "Ceibo Emporio Cafeter\U00eda";
"opening_hours" = {
"open_now" = 0;
"weekday_text" = (
);
};
and thi is my code, but only prints me the first name i want both because i have like 1000 names:
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
print (jsonResult)
if let nombre = ((jsonResult["results"]as?NSArray)?[0]as?NSDictionary)?["name"] {
print (nombre)
}
As always:
Never use NSDictionary / NSArray in Swift when parsing JSON.
Never use mutableContainers in Swift. It's completely useless.
To get all items in the results array use a loop, for convenience and readability use a type alias:
typealias JSONDictionary = [String:Any]
if let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: []) as? JSONDictionary {
print (jsonResult)
if let results = jsonResult["results"] as? [JSONDictionary] {
for result in results {
print(result["name"] as? String ?? "n/a")
if let geometry = result["geometry"] as? JSONDictionary,
let location = geometry["location"] as? JSONDictionary {
let lat = location["lat"] as? Double ?? 0.0
let lng = location["lng"] as? Double ?? 0.0
print("latitude: \(lat)")
print("longitude: \(lng)")
}
}
}
}

Array of dictionaries to JSON in Swift

I'm trying to send an array of dictionaries as one of the parameters to an Alamofire request. However, Alamofire is failing on the request.
class PromoCategory {
var promoCategoryId : Int?
var activityId : Int?
var promoCategoryName : String?
var activityName : String!
var statusCd : Int?
init() {
promoCategoryId = 0
promoCategoryName = ""
}
func getDictFormat() -> [String: Any] {
if activityId == nil { activityId = 0 }
if statusCd == nil { statusCd = 0 }
return [
"promoCategoryId" : "\(promoCategoryId!)",
"activityId" : "\(activityId!)",
"promoCategoryName" : promoCategoryName!,
"activityName" : activityName!,
"statusCd" : "\(statusCd!)"
]
}
}
var promoCat = [[String: Any]]()
for cat in promoCategories {
let element = cat.getDictFormat()
promoCat.append(element)
}
var params : [String : Any] = [:]
params["person_id"] = kPersonId
params["person_promo_id"] = promo.personPromoId
params["promo_page_id"] = promo.promoPageId
params["seq_no"] = promo.seqNo
params["promo_type"] = promoTypeString
params["page_name"] = promo.pageName
params["image_name"] = promo.imageName
params["start_date"] = promo.startDate
params["end_date"] = promo.endDate
params["website"] = promo.website
...
params["promoCategories"] = promoCat
Alamofire.request(promoUrl!, method: .post, parameters: params, encoding: JSONEncoding.default, headers: nil)
.validate()
.responseJSON { response in
switch response.result {
case .success(let data):
self.json = JSON(data)
print(self.json as Any)
DispatchQueue.main.async(execute: { () -> Void in
self.dismiss(animated: true, completion: nil)
HUD.hide()
})
case .failure(let error):
self.logApiError(url: (...)
}
}
The error:
Request failed with error:
responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error
Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character
0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
If I remove the promoCategories parameter, then it works fine. The params object ends up looking like this:
{
address = "";
bgColorBlue = "0.28936631944444";
bgColorGreen = "0.3072916666666701";
bgColorRed = "0.3063227289789799";
city = "";
"contact_name" = "John Smith";
"contact_phone" = 3065554611;
"country_cd" = CA;
"end_date" = "2017-01-26 21:06:08Z";
"facility_name" = "Conexus Arts Centre";
"image_name" = "EV1.20170126210608302479028.jpg";
latitude = 0;
longitude = 0;
"page_name" = "Test Promo";
"person_id" = 1;
"person_promo_id" = 21;
promoCategories = (
{
activityId = 68;
activityName = "Fashion & Beauty";
promoCategoryId = 271;
promoCategoryName = Accessories;
statusCd = 0;
},
{
activityId = 68;
activityName = "Fashion & Beauty";
promoCategoryId = 273;
promoCategoryName = Beauty;
statusCd = 0;
},
{
activityId = 68;
activityName = "Fashion & Beauty";
promoCategoryId = 270;
promoCategoryName = Fashion;
statusCd = 0;
}
);
"promo_page_id" = 0;
"promo_type" = event;
"prov_state_cd" = "";
"seq_no" = 0;
"start_date" = "2017-01-26 21:06:08Z";
website = "";
}
Is this the approach I should be using? Is there something I have missed? Thanks.

Embedded json data in swift three levels

I am having some troubles with some json data. I'm making a weather app and most of the information I parsed works but the weather
this is the council output for the json data as a whole this is the section im having troubles with
the full output of json
{
base = stations;
clouds = {
all = 90;
};
cod = 200;
coord = {
lat = "39.74";
lon = "-104.98";
};
dt = 1427305893;
id = 5419384;
main = {
humidity = 84;
pressure = 1022;
temp = "274.07";
"temp_max" = "275.35";
"temp_min" = "272.15";
};
name = Denver;
rain = {
1h = "0.25";
};
snow = {
1h = "0.17";
};
sys = {
country = US;
id = 532;
message = "0.07829999999999999";
sunrise = 1427288058;
sunset = 1427332632;
type = 1;
};
visibility = 4023;
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
},
{
description = snow;
icon = 13d;
id = 601;
main = Snow;
},
{
description = fog;
icon = 50d;
id = 741;
main = Fog;
},
{
description = mist;
icon = 50d;
id = 701;
main = Mist;
}
);
wind = {
deg = 20;
gust = "14.9";
speed = "12.9";
};
}
i also have it print the keys
[base, id, dt, snow, main, coord, sys, wind, weather, visibility, clouds, cod, name, rain]
I tried to save it as an array but when I set the arry[0] to a string it crashes
my code for the function
func populateLabels(weatherData: NSData){
var jsonError: NSError?
let json = NSJSONSerialization.JSONObjectWithData(weatherData, options: nil, error: &jsonError) as NSDictionary
println(json)
if let city = json["name"] as? String {
CityName.text = city
}
println(json.allKeys)
if let coord = json["coord"] as? NSDictionary {
if let longi = coord["lon"] as? Double {
long.text = String(format: "%.2f", longi)
}
if let lati = coord["lat"] as? Double {
lat.text = String(format: "%.2f", lati)
}
}
if let main = json["main"] as? NSDictionary {
if let temper = main["temp"] as? Double {
temp.text = String(format: "%.2f", temper)
}
}
If anyone knows how to get to the description that would be awesome
thanks js
I got it.. thanks for the help blacksquare, larme, chirag90
if let tasks = json["weather"] as? NSArray
{
if let task = tasks[0] as? NSDictionary
{
if let taskName = task["description"] as? NSString
{
println(taskName)
}
}
}