Nick Schuck Nick Schuck - 2 years ago 117
Swift Question

Swift--Reading in JSON file

Using Xcode 6.4 and programming in swift.

I am typing a program that should read in JSON from a URL. A sample of the JSON can be found at this URL ( and Ive been using this site to parse the JSON in order to read it better (

Now I need to work through the levels of the JSON in order to get to
the actual movie names and image URL's but I am lost at what kind of variable entryDictionary should be. I was thinking it should be an array of dictionaries, and this compiles, but the output of entryDictionary in the console is sloppy looking, starting with Optionl( and not entry{ as it should. And when I go to loop through entryDictionary, I get an error saying entry does not have a subscript of type AnyObject.

So I am asking how I retrieve the im:name fields and im:image from the JSON.

func downloadDataFromURLString(urlString: String) {

//Downloaded data and is now stored in data. Took code out because
//irrelevant to my problem at this point. Data variable has correct
//JSON, now I am trying to parse it.

} else { //download suceeded, time to parse
var error: NSError? = nil
var names = [String]()

if let rootDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) as? [String: AnyObject] {

let feedDictionary = rootDictionary["feed"] as! [String: AnyObject]

let entryDictionary: AnyObject? = feedDictionary["entry"]

println(entryDictionary) //For debugging

//for entry in entryDictionary as! NSArray {
// let name = entryDictionary["name"]
// let image = entryDictionary["image"]
// let movie = Movie(name: name!, image: image!)
// weakSelf!.movies.append(movie)

here is a blueprint of the JSON


mz2 mz2
Answer Source

AnyObject is indeed not subscriptable (you're trying to subscript a variable whose type is AnyObject? with ["feed"]). You should also avoid casting to Cocoa container types like NSArray and NSDictionary whenever you can. Here's an example of how you might get the labels out of the entries array's names array:

import Foundation

func labels(feedDictionary:[String:AnyObject]) -> [String] {
    guard let entries = feedDictionary["entry"] as? [String:AnyObject] else {
        return []

    return entries.flatMap { (key:String, value:AnyObject) -> String? in
        guard key == "im:name" else {
            return nil

        guard let name = value as? [String:String] else {
            return nil

        return name["label"]

I'd however advise against using NSJSONSerialization on its own in Swift for anything but the simplest case, as you end up casting and wrapping optionals until the cows come home.

There are good 3rd party libraries such as Freddy and SwiftyJSON which apply Swift language features to accomplish a very convenient JSON (de)serialization experience.

For instance with Freddy you could express your problem in the following style:

let json = try JSON(data: data)
json.decode("feed", type:Feed.self)

struct Feed: JSONDecodable {
    let entries:[Entry]
    init(json: JSON) throws {
        self.entries = try json.arrayOf("entry", type:Entry.self)

struct Entry:JSONDecodable {
    let name:IMName
    init(json: JSON) throws { = try json.decode("im:name", type:IMName.self)

struct IMName:JSONDecodable {
    let label:String
    init(json: JSON) throws {
        self.label = try json.string("label")
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download