2

I am trying to convert json array of objects to a Dictionary,

I have this code:

func load() { //this function is the first that is executed

    getActivities {
        (response) in
        self.loadActivities(response as NSArray)
    }
}

func getActivities(callback:(NSDictionary) -> ()){ //the next url contains the json array of objects
    request("http://localhost/llancaActivity/public/activity/getListJSON/0/2", callback: callback)
}

func request(url:String, callback:(NSDictionary) -> ()){
    var nsURL : NSURL = NSURL(string: url)!;

    let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL){
        (data, response, error) in
        var error: NSError?
        var response = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary;

        callback(response);
    }

    task.resume();
}


func loadActivities(activities:NSArray){
    for activity in activities {
        println(activity["id"]); //<-- These line never is executed!!!! 
    }
}

If I visit with my browser the next URL: http: // localhost/llancaActivity/public/activity/getListJSON/0/2

I have the next response:

 [{"id":"3","title":"Confer\u00e8ncia de meteorologia \u201cEl canvi clim\u00e0tic\u201d","description":"Hora: 19h\nLloc: Sala de Confer\u00e8ncies de la Casa de Cultura","start_date":"2014-12-13","end_date":"2014-12-13","id_category":null},{"id":"4","title":"Espectacle a favor de la Marat\u00f3 de TV3","description":"Hora: 17h\nEntrada: la voluntat\nLloc: Sala d\u2019Actes de la Casa de Cultura\nOrganitza: Associaci\u00f3 de Puntaires de Llan\u00e7\u00e0\nCol\u00b7labora: Entitats i Associacions de Llan\u00e7\u00e0 i l\u2019Ajuntament de Llan\u00e7\u00e0","start_date":"2014-12-13","end_date":"2014-12-13","id_category":null}]

Please, sorry for my english...

1
  • Did you inspect the response and error variables? What do they contain? Commented Dec 13, 2014 at 1:22

2 Answers 2

1

You are trying to return a dictionary representation of your JSON, but it's not a dictionary. It's an array. Yes, it's an array of dictionaries, but that's a very different thing than a simple dictionary.

So the JSON parsing is simply:

let responseObject = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: &parseError) as NSArray

Integrating that into your request function, it looks like:

func request(urlString: String, callback: (responseObject: NSArray?, error: NSError?) -> ()) {
    let url = NSURL(string: urlString)!

    let task = NSURLSession.sharedSession().dataTaskWithURL(url) {
        data, response, error in

        if data == nil {
            callback(responseObject: nil, error: error)
        } else {
            var parseError: NSError?
            let responseObject = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: &parseError) as? NSArray
            callback(responseObject: responseObject, error: parseError)
        }
    }
    task.resume()
}

Note:

  • I changed the closure to return two parameters, the responseObject and an error (that way the caller can detect errors), but that's up to you.

  • I cast the NSJSONSerialization result to an NSArray, not a NSDictionary.

  • More accurately, I actually cast it to an optional array (using as?), so it will gracefully handle any parsing errors.

Alternatively, you could make this return a Swift array of Swift dictionaries:

func request(urlString: String, callback: (responseObject: [[String: AnyObject]]?, error: NSError?) -> ()) {
    let url = NSURL(string: urlString)!

    let task = NSURLSession.sharedSession().dataTaskWithURL(url) {
        data, response, error in

        if data == nil {
            callback(responseObject: nil, error: error)
        } else {
            var parseError: NSError?
            let responseObject = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: &parseError) as? [[String: AnyObject]]
            callback(responseObject: responseObject, error: parseError)
        }
    }
    task.resume()
}

Clearly, whatever you change the request closure to, you'd want to make the same change to getActivities, but that should be self explanatory.

Sign up to request clarification or add additional context in comments.

Comments

0

With swifty, you only need to issue the following stanza to convert a json array of dicts to an object:

let data = "[{\"id\":\"3\",\"title\":\"Confer\u00e8ncia de meteorologia \u201cEl canvi clim\u00e0tic\u201d\",\"description\":\"Hora: 19h\nLloc: Sala de Confer\u00e8ncies de la Casa de Cultura\",\"start_date\":\"2014-12-13\",\"end_date\":"2014-12-13\",\"id_category\":null}" // .... and the rest of your JSON
let json = JSON(data:data)

Now json will have the parsed data.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.