Access A Value in Wunderground API - swift

I am trying to incorporate Wunderground into my current project. I have looked at several api tutorials, but I can't seem to figure out how to access a certain part of the API. For example, this is sort of what the API looks like:
{
"response": {
"version":"0.1",
"termsofService":"http://www.wunderground.com/weather/api/d/terms.html",
"features": {
"history": 1
}
}
,
"history": {
"date": {
"pretty": "August 9, 2015",
"year": "2015",
"mon": "08",
"mday": "09",
"hour": "12",
"min": "00",
"tzname": "America/Los_Angeles"
},
Let's say I wanted to return only the hour from the API. How would I do that?

A way to parse JSON without frameworks:
typealias JSONdic = [String: AnyObject]
NSURLConnection.sendAsynchronousRequest(NSURLRequest(URL: nsUrl), queue: NSOperationQueue.mainQueue(), completionHandler: { (_, data, _) -> Void in
if let data = data, json = data as? JSONdic, history = json["history"] as? JSONdic, hour = history["hour"] as? String {
println(hour)
}

Related

How to store and access JSON in iOS with Parse Server API format?

My JSON format:
{
"results": [
{
"objectId": "1a8SJaCo2P",
"Name": "Banyan Tree",
"Amount": 300,
"Area": "Nizampura",
"Cuisins": [
"Asian",
"Italian",
"Chaat",
"Awadhi"
],
"Facility": [
"Music",
"Smoking Area",
"Take Away",
"Home Delivery"
],
"Restaurant_Images": {
"__type": "File",
"name": "a138194bc773ffa570a27a640d66f89f_5.jpg",
}
},
]
}
I know how to parse basic json format but it has a {"results":[{user1},{user2},....]} data. So how to parse it?
This is the back4app(parse.com) api requested format
I don't know if you are getting serialized data or rawData. But I'll assume you are getting rawData. So, you may try the following
let serializedJson = try JSONSerialization.jsonObject(with: responseData, options: .mutableContainers)
if let expectedResults = serializedJson as? [String:Any] {
if let users = expectedResults["results"] as? [Any] {
for user in users {
//you will get the values
// now if it is parseable to PFUser
//Then you can have
if let user = user as? PFUser {
//you will have individual user
}
//If not parseable to PFUSer then you can parse it manually
}
}
}

I cannot loop json object on swift xcode

I'm learning swift and objective-c. I want to extract the "show_name" in my Json for all shows.
This is my json :
{
"data": {
"12 Monkeys": {
"air_by_date": 0,
"anime": 0,
"cache": {
"banner": 1,
"poster": 1
},
"indexerid": 272644,
"language": "en",
"network": "Syfy",
"next_ep_airdate": "",
"paused": 0,
"quality": "SD",
"show_name": "12 Monkeys",
"sports": 0,
"status": "Continuing",
"subtitles": 1,
"tvdbid": 272644
},
"2 Broke Girls": {
"air_by_date": 0,
"anime": 0,
"cache": {
"banner": 1,
"poster": 1
},
"indexerid": 248741,
"language": "en",
"network": "CBS",
"next_ep_airdate": "2016-10-10",
"paused": 0,
"quality": "SD",
"show_name": "2 Broke Girls",
"sports": 0,
"status": "Continuing",
"subtitles": 0,
"tvdbid": 248741
},
"American Horror Story": {
"air_by_date": 0,
"anime": 0,
"cache": {
"banner": 1,
"poster": 1
},
"indexerid": 250487,
"language": "en",
"network": "FX (US)",
"next_ep_airdate": "2016-09-14",
"paused": 0,
"quality": "SD",
"show_name": "American Horror Story",
"sports": 0,
"status": "Continuing",
"subtitles": 0,
"tvdbid": 250487
},
This is my code and I use swiftyJson :
class ViewController: UIViewController {
let baseURL = "http://xxx.xxx.xxx.xxx:8083/api/api/?cmd=shows&sort=name&paused=0"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
getJSON()
}
func getJSON(){
let url = NSURL(string: baseURL)
let request = NSURLRequest(URL: url!)
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
let task = session.dataTaskWithRequest(request)
{ (data, response, error) -> Void in
if error == nil {
let swiftyJSON = JSON(data: data!)
print(swiftyJSON)
let title = swiftyJSON["data"]["Sense8"]["show_name"]
print(title)
}else {
print("there was an error")
}
}
task.resume()
}
}
Your swiftyJSON is an array of JSON, (i.e. [JSON]), therefore you are not able to access it by subscript.
You can parse it as follow :
if let dataArray = swiftyJSON.array{
for json in dataArray {
// data information
let showName = json["show_name"].stringValue
let status = json["status"].stringValue
let subtitles = json["subtitles"].stringValue
print(showName)
print(status)
print(subtitles)
}
}

How to fetch the following data into the tableview using Swift?

First lets see the json data.
[
{
"id": "244",
"name": "PIZZAS",
"image": "",
"coupon": "1",
"icon": "",
"order": "1",
"aname": "",
"options": "2",
"subcategory": [
{
"id": "515",
"name": "MARGARITA",
"description": "Cheese and Tomato",
"image": "",
"icon": "",
"coupon": "1",
"order": "1",
"aname": "",
"options": "2",
"item": [
{
"id": "1749",
"name": "9 Inch Thin & Crispy Margarita",
"description": "",
"price": "3.40",
"coupon": "1",
"image": "",
"options": "2",
"order": "1",
"addon": "495",
"aname": "",
"icon": ""
}]
}]
}]
I have used Alamofire and getting response through this code below:
Alamofire.request(.GET, myUrl, parameters:nil , encoding: .JSON)
.validate()
.responseString { response in
print("Response String: \(response.result.value)")
}
.responseJSON { response in
print("Response JSON: \(response.result.value)")
if let jsonResult = response as? Array<Dictionary<String,String>> {
let Name = jsonResult[0]["name"]
let ID = jsonResult[0]["id"]
let Order = jsonResult[0]["order"]
print("JSON: Name: \(Name)")
print("JSON: ID: \(ID)")
print("JSON: Order: \(Order)")
}
}
But after getting response data I am not able to get any value. Here I want to fetch all data like name,id and subcategory - how to implement this?
You have more than one problem there.
First response is of type Response<Anyobject, NSError>, it's not the parsed object you're looking for, instead you should use response.result.value as you did for the log.
Second even if you tried to cast response.result.value to Array<Dictionary<String,String>> it will not pass because in your json data you have ann inner array subcategory which cannot be casted to Dictionary<String, String>
This code should work for you:
Alamofire.request(.GET, myUrl, parameters:nil , encoding: .JSON)
.validate()
.responseString { response in
print("Response String: \(response.result.value)")
}
.responseJSON { response in
print("Response JSON: \(response.result.value)")
let array = response.result.value as! Array<NSDictionary>
for item in array
{
let Name = item["name"]
let ID = item["id"]
let Order = item["order"]
let Subcategories = item["subcategory"] as! Array<NSDictionary>
for subCategory in Subcategories
{
let subId = subCategory["id"]
}
}
}
And here is the results in the playground:
Cheers.

restkit, how to access object in response without object mapping

How can I access the original response json data without using object mapping. I have the followingresponse data. it contains a nextSyncToken which used to execute the query and a collection of items (within the items session).
I created a object mapping of the Item object which represent the contents in items. However, I also need the nextSyncToken field. How can I access it without object mapping. Since the syncToken has no relationship with object mapping. How can i deal with this.
{
"kind": "calendar#events",
"nextSyncToken": "COib8eSw78gCEOib8eSw78gCGAU=",
"items": [
{
"id": "_74rk4cpg84o42b9k8or3gb9k74s34b9p8ks34b9m851kac9m64rk4ci36g",
"created": "2010-04-16T11:09:31.000Z",
"updated": "2010-04-16T11:10:27.487Z",
"summary": "iCal test 1",
"start": {
"dateTime": "2010-03-16T21:00:00+08:00"
},
"end": {
"dateTime": "2010-03-16T22:00:00+08:00"
}
},
{
"id": "_752j2h1j6cq4cba68csjeb9k8p33eba1692k4ba284qj8ea688rj2chh6c",
"status": "confirmed",
"created": "2011-10-18T09:36:02.000Z",
"updated": "2011-10-18T09:36:02.000Z",
"summary": "New Event",
"start": {
"dateTime": "2011-10-18T03:45:00+08:00"
},
"end": {
"dateTime": "2011-10-18T08:15:00+08:00"
}
}
]
}
My code of mapping:
let eventMapping = RKEntityMapping(forEntityForName: "SGEvent", inManagedObjectStore: managedObjectStore)
eventMapping.addAttributeMappingsFromDictionary([
"id": "identifier",
"summary": "summary",
"created": "createdAt",
"updated": "updatedAt",
"location": "location",
"description": "notes",
"start.date": "allDayStart",
"end.date": "allDayEnd"
])
let startTimeMapping = RKAttributeMapping(fromKeyPath: "start.dateTime", toKeyPath: "startTime")
startTimeMapping.valueTransformer = self.googleDateTransformer
eventMapping.addPropertyMapping(startTimeMapping)
let endTimeMapping = RKAttributeMapping(fromKeyPath: "end.dateTime", toKeyPath: "endTime")
endTimeMapping.valueTransformer = self.googleDateTransformer
eventMapping.addPropertyMapping(endTimeMapping)
eventMapping.identificationAttributes = ["identifier"]
let responseDescriptor = RKResponseDescriptor(mapping: eventMapping, method: .GET,
pathPattern: "calendars/:calendarId/events", keyPath: "items",
statusCodes: RKStatusCodeIndexSetForClass(RKStatusCodeClass.Successful))
objectManager.addResponseDescriptor(responseDescriptor)
My request operation:
objectManager.getObjectsAtPath("calendars/\(identifier)/events",
parameters: [self.ACCESS_TOKEN: accessToken], success: { (operation, results) -> Void in
callback?(results: nil, error: nil)
}) { (_, error) -> Void in
print(error)
}
Generally you would add other response descriptors with appropriate mappings to deal with this issue.
When using objectManager.getObjectsAtPath you can get the raw data, assuming that you have some other response descriptor which will result in the success block being called, by navigating to the response data in the HTTP operation (which you can then unpack however you see fit):
operation.HTTPRequestOperation.responseData
(or use responseString instead of responseData).
if let dict = try? NSJSONSerialization.JSONObjectWithData(operation.HTTPRequestOperation.responseData, options: .AllowFragments) as? [String: AnyObject],
let nextSyncToken = dict?["nextSyncToken"] as? String{
print(nextSyncToken)//get the nextSyncToken
}

Swift, ObjectMapper: path for nested array

I have json from http://openweathermap.org/, and it looks like this:
{
"coord": {
"lon": 4.85,
"lat": 45.75
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04d"
}
],
"base": "cmc stations",
"main": {
"temp": 278.988,
"pressure": 985.88,
"humidity": 92,
"temp_min": 278.988,
"temp_max": 278.988,
"sea_level": 1032.68,
"grnd_level": 985.88
},
"wind": {
"speed": 1.8,
"deg": 355
},
"clouds": {
"all": 80
},
"dt": 1445249394,
"sys": {
"message": 0.0037,
"country": "FR",
"sunrise": 1445234548,
"sunset": 1445273273
},
"id": 2996944,
"name": "Lyon",
"cod": 200
}
I'm using Alamofire 3.0 for networking, ObjectMapper for mapping json to model, and AlamofireObjectMapper extension to get model objects from request instead of json.
Now I need to get weather description, but don't know how to write path for it. Tried ["weather.0.description"], ["weather.$0.description"], but these are not working, and my weather description is nil.
Here is my model:
class WCurrentWeather: Mappable {
var weatherDescription: String?
var tempriture: Double?
var clouds: Double?
var rain: Double?
var humidity: Double?
var pressure: Double?
var sunrise: NSDate?
var sunset: NSDate?
required init?(_ map: Map){
}
func mapping(map: Map) {
weatherDescription <- map["weather.0.description"]
tempriture <- map["main.temp"]
clouds <- map["clouds.all"]
rain <- map["rain.1h"]
humidity <- map["main.humidity"]
pressure <- map["main.pressure"]
sunrise <- (map["sys.sunrise"], DateTransform())
sunset <- (map["sys.sunset"], DateTransform())
}
}
and my request:
Alamofire.request(.GET, URL, parameters: params)
.responseObject { (response: WCurrentWeather?, error: ErrorType?) in
completionHandler(response, error)
}
Is there any way to get this working.
Thanks in advance.
I have forked ObjectMapper, and added this functionality, and thanks to Tristan Himmelman it is already merged, so now you can access to nested array elements like this map["weather.0.description"]
What you are looking for is:
let jsonDict = // You dict
jsonDict["weather"][0]["description"]
I am just giving you a direction. You would need to align it with Swift type casting rules. Good luck!