Cannot parse JSON data correctly - ios

I've been trying to parse this JSON data, but for some reason have not been able to. The code and JSON that I have are below. I want it to show each page in pages and print it to the console. The code works, it just doesn't actually process anything after the if let pages = JSON[] (or so it seems,) because it won't print my for loop or page in pages. Code and JSON is below.
Here's the JSON data I'm trying to parse:
{"43993167":{"summonerId":43993167,"pages":[{"id":54725209,"name":"Jinx","current":false,"slots":[{"runeSlotId":1,"runeId":5245},{"runeSlotId":2,"runeId":5245},{"runeSlotId":3,"runeId":5245},{"runeSlotId":4,"runeId":5245},{"runeSlotId":5,"runeId":5245},{"runeSlotId":6,"runeId":5245},{"runeSlotId":7,"runeId":5245},{"runeSlotId":8,"runeId":5245},{"runeSlotId":9,"runeId":5245},{"runeSlotId":10,"runeId":5317},{"runeSlotId":11,"runeId":5317},{"runeSlotId":12,"runeId":5317},{"runeSlotId":13,"runeId":5317},{"runeSlotId":14,"runeId":5317},{"runeSlotId":15,"runeId":5317},{"runeSlotId":16,"runeId":5317},{"runeSlotId":17,"runeId":5317},{"runeSlotId":18,"runeId":5317},{"runeSlotId":19,"runeId":5289},{"runeSlotId":20,"runeId":5289},{"runeSlotId":21,"runeId":5289},{"runeSlotId":22,"runeId":5289},{"runeSlotId":23,"runeId":5289},{"runeSlotId":24,"runeId":5289},{"runeSlotId":25,"runeId":5289},{"runeSlotId":26,"runeId":5289},{"runeSlotId":27,"runeId":5289},{"runeSlotId":28,"runeId":5337},{"runeSlotId":29,"runeId":5337},{"runeSlotId":30,"runeId":5337}]},{"id":54725210,"name":"support","current":false,"slots":[{"runeSlotId":1,"runeId":5255},{"runeSlotId":2,"runeId":5255},{"runeSlotId":3,"runeId":5255},{"runeSlotId":4,"runeId":5255},{"runeSlotId":5,"runeId":5255},{"runeSlotId":6,"runeId":5255},{"runeSlotId":7,"runeId":5247},{"runeSlotId":8,"runeId":5247},{"runeSlotId":9,"runeId":5247},{"runeSlotId":10,"runeId":5317},{"runeSlotId":11,"runeId":5317},{"runeSlotId":12,"runeId":5317},{"runeSlotId":13,"runeId":5317},{"runeSlotId":14,"runeId":5317},{"runeSlotId":15,"runeId":5317},{"runeSlotId":16,"runeId":5317},{"runeSlotId":17,"runeId":5317},{"runeSlotId":18,"runeId":5317},{"runeSlotId":19,"runeId":5289},{"runeSlotId":20,"runeId":5289},{"runeSlotId":21,"runeId":5289},{"runeSlotId":22,"runeId":5289},{"runeSlotId":23,"runeId":5289},{"runeSlotId":24,"runeId":5289},{"runeSlotId":25,"runeId":5289},{"runeSlotId":26,"runeId":5289},{"runeSlotId":27,"runeId":5289},{"runeSlotId":28,"runeId":5347},{"runeSlotId":29,"runeId":5365},{"runeSlotId":30,"runeId":5365}]},{"id":64389802,"name":"Twisted Fate","current":false,"slots":[{"runeSlotId":1,"runeId":5273},{"runeSlotId":2,"runeId":5273},{"runeSlotId":3,"runeId":5273},{"runeSlotId":4,"runeId":5273},{"runeSlotId":5,"runeId":5273},{"runeSlotId":6,"runeId":5273},{"runeSlotId":7,"runeId":5273},{"runeSlotId":8,"runeId":5273},{"runeSlotId":9,"runeId":5273},{"runeSlotId":10,"runeId":5315},{"runeSlotId":11,"runeId":5315},{"runeSlotId":12,"runeId":5315},{"runeSlotId":13,"runeId":5315},{"runeSlotId":14,"runeId":5315},{"runeSlotId":15,"runeId":5316},{"runeSlotId":16,"runeId":5316},{"runeSlotId":17,"runeId":5316},{"runeSlotId":18,"runeId":5316},{"runeSlotId":19,"runeId":5289},{"runeSlotId":20,"runeId":5289},{"runeSlotId":21,"runeId":5289},{"runeSlotId":22,"runeId":5289},{"runeSlotId":23,"runeId":5289},{"runeSlotId":24,"runeId":5289},{"runeSlotId":25,"runeId":5289},{"runeSlotId":26,"runeId":5289},{"runeSlotId":27,"runeId":5289},{"runeSlotId":28,"runeId":5365},{"runeSlotId":29,"runeId":5365},{"runeSlotId":30,"runeId":5365}]},{"id":69919016,"name":"Ahri","current":false,"slots":[{"runeSlotId":1,"runeId":5273},{"runeSlotId":2,"runeId":5273},{"runeSlotId":3,"runeId":5273},{"runeSlotId":4,"runeId":5273},{"runeSlotId":5,"runeId":5273},{"runeSlotId":6,"runeId":5273},{"runeSlotId":7,"runeId":5273},{"runeSlotId":8,"runeId":5273},{"runeSlotId":9,"runeId":5273},{"runeSlotId":10,"runeId":5316},{"runeSlotId":11,"runeId":5316},{"runeSlotId":12,"runeId":5316},{"runeSlotId":13,"runeId":5316},{"runeSlotId":14,"runeId":5316},{"runeSlotId":15,"runeId":5316},{"runeSlotId":16,"runeId":5316},{"runeSlotId":17,"runeId":5316},{"runeSlotId":18,"runeId":5316},{"runeSlotId":19,"runeId":5289},{"runeSlotId":20,"runeId":5289},{"runeSlotId":21,"runeId":5289},{"runeSlotId":22,"runeId":5289},{"runeSlotId":23,"runeId":5289},{"runeSlotId":24,"runeId":5289},{"runeSlotId":25,"runeId":5289},{"runeSlotId":26,"runeId":5289},{"runeSlotId":27,"runeId":5289},{"runeSlotId":28,"runeId":5357},{"runeSlotId":29,"runeId":5357},{"runeSlotId":30,"runeId":5357}]},{"id":71240898,"name":"Gragas","current":false,"slots":[{"runeSlotId":1,"runeId":5247},{"runeSlotId":2,"runeId":5247},{"runeSlotId":3,"runeId":5247},{"runeSlotId":4,"runeId":5247},{"runeSlotId":5,"runeId":5247},{"runeSlotId":6,"runeId":5247},{"runeSlotId":7,"runeId":5247},{"runeSlotId":8,"runeId":5247},{"runeSlotId":9,"runeId":5247},{"runeSlotId":10,"runeId":5318},{"runeSlotId":11,"runeId":5318},{"runeSlotId":12,"runeId":5318},{"runeSlotId":13,"runeId":5318},{"runeSlotId":14,"runeId":5318},{"runeSlotId":15,"runeId":5318},{"runeSlotId":16,"runeId":5318},{"runeSlotId":17,"runeId":5318},{"runeSlotId":18,"runeId":5316},{"runeSlotId":19,"runeId":5290},{"runeSlotId":20,"runeId":5290},{"runeSlotId":21,"runeId":5290},{"runeSlotId":22,"runeId":5290},{"runeSlotId":23,"runeId":5290},{"runeSlotId":24,"runeId":5290},{"runeSlotId":25,"runeId":5290},{"runeSlotId":26,"runeId":5290},{"runeSlotId":27,"runeId":5290},{"runeSlotId":28,"runeId":5357},{"runeSlotId":29,"runeId":5357},{"runeSlotId":30,"runeId":5357}]},{"id":71240899,"name":"Zac","current":false,"slots":[{"runeSlotId":1,"runeId":5273},{"runeSlotId":2,"runeId":5273},{"runeSlotId":3,"runeId":5273},{"runeSlotId":4,"runeId":5273},{"runeSlotId":5,"runeId":5273},{"runeSlotId":6,"runeId":5273},{"runeSlotId":7,"runeId":5273},{"runeSlotId":8,"runeId":5273},{"runeSlotId":9,"runeId":5273},{"runeSlotId":10,"runeId":5318},{"runeSlotId":11,"runeId":5318},{"runeSlotId":12,"runeId":5318},{"runeSlotId":13,"runeId":5318},{"runeSlotId":14,"runeId":5318},{"runeSlotId":15,"runeId":5318},{"runeSlotId":16,"runeId":5318},{"runeSlotId":17,"runeId":5318},{"runeSlotId":18,"runeId":5325},{"runeSlotId":19,"runeId":5295},{"runeSlotId":20,"runeId":5295},{"runeSlotId":21,"runeId":5295},{"runeSlotId":22,"runeId":5296},{"runeSlotId":23,"runeId":5289},{"runeSlotId":24,"runeId":5289},{"runeSlotId":25,"runeId":5289},{"runeSlotId":26,"runeId":5289},{"runeSlotId":27,"runeId":5289},{"runeSlotId":28,"runeId":5357},{"runeSlotId":29,"runeId":5357},{"runeSlotId":30,"runeId":5357}]},{"id":71240900,"name":"Volibear","current":false,"slots":[{"runeSlotId":1,"runeId":5247},{"runeSlotId":2,"runeId":5247},{"runeSlotId":3,"runeId":5247},{"runeSlotId":4,"runeId":5247},{"runeSlotId":5,"runeId":5247},{"runeSlotId":6,"runeId":5247},{"runeSlotId":7,"runeId":5247},{"runeSlotId":8,"runeId":5247},{"runeSlotId":9,"runeId":5247},{"runeSlotId":10,"runeId":5317},{"runeSlotId":11,"runeId":5317},{"runeSlotId":12,"runeId":5317},{"runeSlotId":13,"runeId":5317},{"runeSlotId":14,"runeId":5317},{"runeSlotId":15,"runeId":5317},{"runeSlotId":16,"runeId":5317},{"runeSlotId":17,"runeId":5317},{"runeSlotId":18,"runeId":5317},{"runeSlotId":19,"runeId":5295},{"runeSlotId":20,"runeId":5295},{"runeSlotId":21,"runeId":5295},{"runeSlotId":22,"runeId":5289},{"runeSlotId":23,"runeId":5289},{"runeSlotId":24,"runeId":5289},{"runeSlotId":25,"runeId":5289},{"runeSlotId":26,"runeId":5289},{"runeSlotId":27,"runeId":5289},{"runeSlotId":28,"runeId":5365},{"runeSlotId":29,"runeId":5365},{"runeSlotId":30,"runeId":5365}]},{"id":71240901,"name":"I AM SMURF","current":false,"slots":[{"runeSlotId":1,"runeId":5273},{"runeSlotId":2,"runeId":5273},{"runeSlotId":3,"runeId":5273},{"runeSlotId":4,"runeId":5273},{"runeSlotId":5,"runeId":5273},{"runeSlotId":6,"runeId":5273},{"runeSlotId":7,"runeId":5273},{"runeSlotId":8,"runeId":5273},{"runeSlotId":9,"runeId":5273},{"runeSlotId":10,"runeId":5317},{"runeSlotId":11,"runeId":5317},{"runeSlotId":12,"runeId":5317},{"runeSlotId":13,"runeId":5317},{"runeSlotId":14,"runeId":5317},{"runeSlotId":15,"runeId":5317},{"runeSlotId":16,"runeId":5317},{"runeSlotId":17,"runeId":5317},{"runeSlotId":18,"runeId":5317},{"runeSlotId":19,"runeId":5298},{"runeSlotId":20,"runeId":5298},{"runeSlotId":21,"runeId":5298},{"runeSlotId":22,"runeId":5298},{"runeSlotId":23,"runeId":5298},{"runeSlotId":24,"runeId":5298},{"runeSlotId":25,"runeId":5298},{"runeSlotId":26,"runeId":5298},{"runeSlotId":27,"runeId":5298},{"runeSlotId":28,"runeId":5357},{"runeSlotId":29,"runeId":5357},{"runeSlotId":30,"runeId":5357}]},{"id":71240902,"name":"Graves","current":true,"slots":[{"runeSlotId":1,"runeId":5245},{"runeSlotId":2,"runeId":5245},{"runeSlotId":3,"runeId":5245},{"runeSlotId":4,"runeId":5245},{"runeSlotId":5,"runeId":5245},{"runeSlotId":6,"runeId":5245},{"runeSlotId":7,"runeId":5245},{"runeSlotId":8,"runeId":5245},{"runeSlotId":9,"runeId":5245},{"runeSlotId":10,"runeId":5317},{"runeSlotId":11,"runeId":5317},{"runeSlotId":12,"runeId":5317},{"runeSlotId":13,"runeId":5317},{"runeSlotId":14,"runeId":5317},{"runeSlotId":15,"runeId":5317},{"runeSlotId":16,"runeId":5317},{"runeSlotId":17,"runeId":5317},{"runeSlotId":18,"runeId":5317},{"runeSlotId":19,"runeId":5290},{"runeSlotId":20,"runeId":5290},{"runeSlotId":21,"runeId":5290},{"runeSlotId":22,"runeId":5290},{"runeSlotId":23,"runeId":5290},{"runeSlotId":24,"runeId":5290},{"runeSlotId":25,"runeId":5290},{"runeSlotId":26,"runeId":5290},{"runeSlotId":27,"runeId":5290},{"runeSlotId":28,"runeId":5337},{"runeSlotId":29,"runeId":5337},{"runeSlotId":30,"runeId":5335}]},{"id":71240903,"name":"Vi","current":false,"slots":[{"runeSlotId":1,"runeId":5245},{"runeSlotId":2,"runeId":5245},{"runeSlotId":3,"runeId":5245},{"runeSlotId":4,"runeId":5245},{"runeSlotId":5,"runeId":5245},{"runeSlotId":6,"runeId":5245},{"runeSlotId":7,"runeId":5245},{"runeSlotId":8,"runeId":5245},{"runeSlotId":9,"runeId":5245},{"runeSlotId":10,"runeId":5317},{"runeSlotId":11,"runeId":5317},{"runeSlotId":12,"runeId":5317},{"runeSlotId":13,"runeId":5317},{"runeSlotId":14,"runeId":5317},{"runeSlotId":15,"runeId":5317},{"runeSlotId":16,"runeId":5317},{"runeSlotId":17,"runeId":5317},{"runeSlotId":18,"runeId":5317},{"runeSlotId":19,"runeId":5290},{"runeSlotId":20,"runeId":5290},{"runeSlotId":21,"runeId":5290},{"runeSlotId":22,"runeId":5295},{"runeSlotId":23,"runeId":5295},{"runeSlotId":24,"runeId":5295},{"runeSlotId":25,"runeId":5290},{"runeSlotId":26,"runeId":5290},{"runeSlotId":27,"runeId":5290},{"runeSlotId":28,"runeId":5335},{"runeSlotId":29,"runeId":5335},{"runeSlotId":30,"runeId":5335}]},{"id":71240904,"name":"Reksai","current":false,"slots":[{"runeSlotId":1,"runeId":5245},{"runeSlotId":2,"runeId":5245},{"runeSlotId":3,"runeId":5245},{"runeSlotId":4,"runeId":5245},{"runeSlotId":5,"runeId":5245},{"runeSlotId":6,"runeId":5245},{"runeSlotId":7,"runeId":5245},{"runeSlotId":8,"runeId":5245},{"runeSlotId":9,"runeId":5245},{"runeSlotId":10,"runeId":5317},{"runeSlotId":11,"runeId":5317},{"runeSlotId":12,"runeId":5317},{"runeSlotId":13,"runeId":5317},{"runeSlotId":14,"runeId":5317},{"runeSlotId":15,"runeId":5317},{"runeSlotId":16,"runeId":5317},{"runeSlotId":17,"runeId":5317},{"runeSlotId":18,"runeId":5317},{"runeSlotId":19,"runeId":5290},{"runeSlotId":20,"runeId":5290},{"runeSlotId":21,"runeId":5290},{"runeSlotId":22,"runeId":5290},{"runeSlotId":23,"runeId":5290},{"runeSlotId":24,"runeId":5290},{"runeSlotId":25,"runeId":5290},{"runeSlotId":26,"runeId":5290},{"runeSlotId":27,"runeId":5290},{"runeSlotId":28,"runeId":5335},{"runeSlotId":29,"runeId":5335},{"runeSlotId":30,"runeId":5335}]}]}}
Here's my code for trying to parse it:
let task = session.dataTaskWithURL(url) { data, response, error in
if let httpResponse = response as? NSHTTPURLResponse {
switch httpResponse.statusCode {
case 200..<300:
if let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? [String : AnyObject] {
println("json working") //this is as far as it will go, won't process the next part
//println(json)
if let pages = json["pages"] as? [[String : AnyObject]] {
println("stat summary working")
for page in pages {
println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
println(page)
}
}
}
default: println("Not Ok")
}
}
}
task.resume()
URL is just the URL that shows the JSON data that I posted above the code.

You're not accessing your json correctly, by that I mean the path you provide in json["pages"] is not a valid one. Look at the data closer; {"43993167":{"summonerId":43993167,"pages"
You have an object, inside it the first thing is another object with the name/key "43993167", under that it has pages. So you would need json["43993167"]["pages"] to access the data you're trying to reach.
That being said, I can tell just by assumption you're dealing with a dictionary of summoner objects where the key is the summonerid and then you're trying to look at their rune page data... A better design would be to deserialize into something that reflects that structure (like a dictionary of summoner objects) then iterate that dictionary.
Ultimately you have something like this;
rootLevelDictionary[]
summoner
summonerId
pages[]
id
name
current
slots[]
runeObject
runeSlotId
runeId
That's the basic structure of your json. If I have time I'll turn it into a valid json-schema but hopefully that is enough to get you unblocked.

Because json["pages"] doesnt exist, its nested inside "43993167".
json["43993167"]["pages"] is what you need

Finally got it to work. Had to change the code a little bit. Here's how it looks now:
let task = session.dataTaskWithURL(url) { data, response, error in
if let httpResponse = response as? NSHTTPURLResponse {
switch httpResponse.statusCode {
case 200..<300:
if let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary, let include = json.objectForKey("\(self.idNumber)") as? NSDictionary {
println("json working")
//println(json)
if let pages = include["pages"] as? [[String : AnyObject]] {
println("stat summary working")
for page in pages {
println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
println(page)
}
}
}
default: println("Not Ok")
}
}
}
task.resume()

Related

iOS Swift Casting JSON response with strange format to dictionary

I'm attempting to cast a JSON response in swift to a useable dictionary. This seemed like a simple task, however the JSON response I am getting is formatted strangely, and no matter what I try, I am unable to cast it to a dictionary. All of the google examples I've been able to find assume that the format of the JSON response will be as follows:
{
"someKey": 42.0,
"anotherKey": {
"someNestedKey": true
},
{
"someKey": 42.0,
"anotherKey": {
"someNestedKey": true
}
However, the print response in swift I'm receiving using the code below is formatted as follows:
{assets = (
{
"someKey": 42.0,
"anotherKey": {
"someNestedKey": true
},
{
"someKey": 42.0,
"anotherKey": {
"someNestedKey": true
}
);
}
Here is as far as I was able to get in attempting to cast this data to a dictionary in swift. It adds "assets" as the single key in the dictionary, with the value of that key being the entire rest of the response.
let url = URL(string: "https://\(apiKey):\(password)#\(yourStore).myshopify.com/admin/themes/\(currentThemeID)/assets.json")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error)
} else {
if let urlContent = data {
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: [.allowFragments, JSONSerialization.ReadingOptions.mutableContainers])
print(jsonResult)
if let dictionary = jsonResult as? [String: [String]] {
print(dictionary)
}
} catch {
print("json processing failed")
}
}
}
}
task.resume()
I'm pretty sure the hang up resides around the presence of the two "parenthesis" and "semi-colon" in the JSON response. I'm unable to find any documentation on how those characters effect the response, or on how to handle them when attempting to down-cast in swift.
Any help would be appreciated!
EDIT:
I've pulled up the JSON response in my browser, and here is the formatting:
{"assets":[{"key":"assets\/1-1.png","public_url":"https:\/\/cdn.shopify.com\/s\/files\/1\/0810\/2125\/t\/22\/assets\/1-1.png?5272098227851596200","created_at":"2016-05-16T16:58:27-05:00","updated_at":"2016-05-16T16:58:27-05:00","content_type":"image\/png","size":9127,"theme_id":124078279}{"key":"templates\/search.liquid","public_url":null,"created_at":"2016-05-16T16:59:04-05:00","updated_at":"2016-05-16T16:59:04-05:00","content_type":"text\/x-liquid","size":2931,"theme_id":124078279}]}
This JSON response does not have the assets = (); portion in it, and is formatted correctly. Somehow my swift code is improperly parsing the data?
Repeatedly cast as [String: Any] to get down to the part of the JSON response you want.
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: [.allowFragments, JSONSerialization.ReadingOptions.mutableContainers])
print(jsonResult)
guard
let dictionary = jsonResult as? [String: Any],
let assetData = dictionary["assets"] as? [String: Any] else {
print("The JSON structure doesn't meet our expectations \(urlContent)")
return
}
print(assetData)
} catch {
print("json processing failed")
}

Reading Data in API response | iOS

I'm trying to integrate a login API in my iOS project. When i hit that API in browser it gives me correct JSON response. Whereas, when i call it in my app, i'm unable to read JSON. Code is as:
let url = NSURL(string: "myURL")
let request = NSURLRequest(URL: url!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
print (error)
}
do {
//jsonDict is always nil
if let jsonDict = try self.jsonFromData(data!) {
print (jsonDict)
}
}
catch {
print ("hi")
}
}
jsonFromData is as:
private func jsonFromData(jsonData: NSData) throws -> [NSDictionary]?
{
var jsonDict: [NSDictionary]? = nil
do
{
jsonDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) as? [NSDictionary]
}
catch
{
throw(error)
}
return jsonDict
}
Response of API, when hit in browser is as:
Please help me, what i am doing wrong. Thanks.
UPDATE:
I just checked that if i convert data to String, it gives correct value. i.e.
let string = NSString(data: jsonData, encoding: NSASCIIStringEncoding)
print (string)
//OUTPUT: Optional({"Authenticated":true,"CustomerID":000,"CustomerName":"TEMP","Members":[{"MemberID":000,"MemberNumber":"000","MembershipID":00,"MembershipExpiration":"\/Date(1517464799000-0600)\/","ValidBuyerTypes":[0]}]})
Look at your code where you decode the JSON and the as? statement. You are trying to get an array of NSDictionary. Your JSON as printed contains a single dictionary, not an array.
This looks right to me. The only thing I can think is that (despite what the string output looks like) the top level container of your response is NOT an NSDictionary. In your jsonFromData function, instead of assuming the result of JSONObjecWithData will be an NSDictionary, I would say:
let iDunnoWhatThisIs = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) // don't cast this to NSDictionary
and see what you get back. It should either be a dictionary or an array, however, since you have NSJSONReadingOptions.AllowFragments set for the options, it's possible that it could be something else entirely. Start with making SURE you're actually getting back what you're assuming you are and go from there.
Try using NSKeyedUnarchiver instead:
jsonDict = NSKeyedUnarchiver.unarchiveObjectWithData(jsonData)! as NSDictionary

iOS programming, fetching JSON data

I have added to my project the SwiftyJSON.swift file and I am trying to get some data from the web. Now my project runs but only until the line where I am trying to get the array from json in a dictionary. I cannot understand where the problem is, but I am guessing it has to be something very stupid as I am just in the beginning with learning swift.
I am just trying to print in the console the name of all the movies from that url and after I manage to achieve this performance, I will try to get the summary of the movie as well and then put them in a TableView.
import UIKit
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//grab the status code and check if the transfer was successful == 200
let requestURL: NSURL = NSURL(string: "https://itunes.apple.com/us/rss/topmovies/limit=50/json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
//sort through the stations key and cast the data into an array of dictionaries
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
print("bbbbb")
// From here on, it doesn't print anything anymore
if let movies = json["entry"] as? [[String: AnyObject]] {
print(movies)
print("test")
for movie in movies {
if let name = movie["name"] as? String {
print("mmmm")
print("%# (Built %#)",name)
}
}
}
}catch {
print("Error with Json: \(error)")
}
}
}
task.resume()
entry is an json array, Use .array
if let movies = json["entry"].array {
for movie in movies {
// Do stuff
}
}
Also a general tip. Do not cast the values e.g.
movie["something"] as? String
Rather use the built in features:
movie["something"].string
Update
Looking closer on your code I see that you are acctually not using SwiftyJSON.swift at all.
To use Swifty you parse the json text like this and get a JSON object:
let jsonObj = JSON(data: yourData) // data is a NSData
Please have another look at the documentation:
https://github.com/SwiftyJSON/SwiftyJSON
I think you are reading the section "Why is the typical JSON handling in Swift NOT good?". That section explains the native and "bad" way of managing json in Swift, the real documentation is further down.

How to get the JSON data in my app

So , I want to make an app that calls the API of forecast.io to get weather in my app. Someone said me to use SwiftyJSON and Alamofire . I'm new to programming and this is my first app so i dont really know how to do it right. That's my code for now , but I don't know if it is right or not , it works but the call isn't made and I need to enter the JSON data to get the "temperature" data:
// Get Weather
let URL = "https://api.forecast.io/forecast/apikey/\(lat),\(long)"
Alamofire.request(.GET, URL, parameters: nil)
.responseJSON { response in
let jsonData: AnyObject?
do {
jsonData = try NSJSONSerialization.JSONObjectWithData(response.data!, options: [])
} catch {
}
}
It only says that "jsonData" was never used. That's all i wrote for getting the call.
Once you have the jsonData variable, you can use it like a regular NSDictionary by putting the following lines in the do block after the first line
guard let jsonDict = jsonData as? NSDictionary else {return}
If you want to get the current forecast, all you have to do is
guard let currentForecast = jsonDict["currently"] as? NSDictionary else {return}
And then you can get its properties using this link
guard let temperature = currentForecast["apparentTemperature"] as? Int else {return}
All in all, your code should look something like this
let URL = "https://api.forecast.io/forecast/apikey/\(lat),\(long)"
Alamofire.request(.GET, URL, parameters: nil)
.responseJSON { response in
let jsonData: AnyObject?
do {
jsonData = try NSJSONSerialization.JSONObjectWithData(response.data!, options: [])
guard let jsonDict = jsonData as? NSDictionary else {return}
guard let currentForecast = jsonDict["currently"] as? NSDictionary else {return}
guard let temperature = currentForecast["apparentTemperature"] as? Int else {return}
print(temperature)
} catch {
//TODO: Handle errors
}
}
The catch block is to handle errors, so if it could not parse the JSON that's where you would display an alert saying that there was an error.

How To Fetch and Parse JSON Using Swift 2 + XCode 7 + iOS 9 [duplicate]

This question already has answers here:
How to parse JSON in Swift using NSURLSession
(5 answers)
Closed 7 years ago.
Was looking for useful tutorials for networking with Swift 2 and iOS 9, but it seems that topic has no content online. I have watched the WWDC session Networking with NSURLSession But I couldn't adapt the new API of iOS9 to have an asynchronous way to fetch and parse JSON data. What I have tried:
do {
if let url = NSURL(string: "site/api.php?option=fetchOps"),
let data = NSData(contentsOfURL: url),
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [[String:AnyObject]] {
}
} catch let error as NSError {
print(error.description)
}
Please share your experience with networking on iOS9 and Swift2, any best practices maybe a Singleton class for networking and parsing maybe an ORM ?
Easy way to make a request for you:
How to make an HTTP request in Swift?
Or If you want to send request by your own:
HTTP POST error Handling in Swift 2
Converting a String to JSON Object:
Just as an example, here I've converted a NSString
First of all convert the NSString to NSDictionary
static func convert(src: NSString) -> NSDictionary {
// convert String to NSData
let data = src.dataUsingEncoding(NSUTF8StringEncoding)
var error: NSError?
// convert NSData to 'AnyObject'
let anyObj: AnyObject?
do {
anyObj = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(rawValue: 0))
} catch let error1 as NSError {
error = error1
anyObj = nil
}
if(error != nil) {
// If there is an error parsing JSON, print it to the console
print("JSON Error \(error!.localizedDescription)")
//self.showError()
return NSDictionary()
} else {
return anyObj as! NSDictionary
}
}
And then, use it like this
if let name = dictionary["name"] as? String {
self.name = name
}
You can use the converted JSON to make an object like this
import Foundation
class Student {
var name="";
init(dictionary: NSDictionary) {
let _NAME = "name"
if let name = dictionary[_NAME] as? String {
self.name = name
}
}
}
oha, well ... search for async network calls for swift. You will find many things.
But yea... Create an NSMutableRequest, init eith the URL, set the method to GET or POST.
Now make:
let task = NSURLSession.sharedSession().dataTaskWithRequest(yourMutableRequest) {
data, response, error in
// do your stuff here
}
task.resume()
This will run asynchron, so you need to think about a way to handle the data. At first your response data is in the variable data this is a type of NSData. You will need this to create your dictionary:
let dictionaryOrArray = NSJSONSerialization.JSONObjectWithData(data, options:.MutableContainers, error: nil)
Maybe you need to put this in a guard or if let statemant.
Now you need to pass the data to the function caller... you can do this in many ways, i prefer success and failure blocks
You call your Request function and you provide a success and failure block. This blocks will do what should happen in the end:
let successBlock:[AnyObject]->Void = { response in
// handle your dict
}
let failureBlock:NSError->Void = { error in
// error handling
}
YourClass.fetchSomething(someURL, parameters: params, requestMethod: method, success : successBlock, failure: failureBlock)
Something like that. In your request block with data, response, error you just do the following:
If error {
failure(error)
return
}
success(dictionaryOrArray)

Resources