-1

I'm successfully making a POST request and getting data back in return. I can then print that statement in the form of an NSString, after converting of course.

However, I want to save the returned json in usable variables/constants so I can display in the next subsequent screens. I'm having trouble getting various JSON parsing code to work.

I think some of my weaknesses is not understanding the form of 'data', that is returned when I use the NSURLSession. I used code I found elsewhere, and don't quite grasp what the return types are. Is that data from the code below in JSON? NSData?

Anyways, this script works until I start parsing through the data, trying to make sense of how to abstract the array.

If it helps my console returns my print statements (after converting to a NSString) as such:

Optional({
  "result":   {
  "girl": "monica",
  "waist": 22.0,
  "hair": "Brunette",
  "location": "Los Angeles"
  }
})

When I try and use the NSJSON serialization framework, the output of that object looks like this, which is supposedly an NSDictionary?:

{
result:   {
  girl: monica;
  waist: 22.0;
  hair: Brunette;
  location: "Los Angeles";
  }
}

A few things confuse me. Why did the quotation marks go away, and what is the optional and extra "result" attribute... Here's my code starting from NSURL request to end of code

    let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:5000")!)
    request.HTTPMethod = "POST"
    let postString = "color=\(finalDataPassed)&type=\(thirdDataPassed)&hair=\(dataPassed)&location=\(secondDataPassed)"

    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        if error != nil {
            println("error=\(error)")
            return
        }

        println("response = \(response)")

        let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)

        println(responseString)
        var error: NSError?

        let result = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error)
            as? NSDictionary

        if(error != nil) {
            println(error!.localizedDescription)
            let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
            println("Error could not parse JSON: '\(jsonStr)'")
        }
        else {
            if let parseJSON = result {

                println(parseJSON)
                for item in parseJSON { // loop through data items
                    let obj = (item as! NSDictionary).objectForKey("result") as! NSDictionary
                    for (key, value) in obj {
                        println("Property: \"\(key as! String)\"")
                    }
                }

            }
            else {

                let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
                println("Error could not parse JSON: \(jsonStr)")

            }
        }
petermaxstack
  • 325
  • 1
  • 3
  • 10

2 Answers2

0

You have an dictionary inside a dictionary:

{
result: <- Key first dictionary    
  {
  girl: monica; <- start of second dictionary
  waist: 22.0;
  hair: Brunette;
  location: "Los Angeles"; <- end of second dictionary
  }
}

For a generic approach you can use:

   for item in dataArray { // loop through data items
        let obj = item.first as! NSDictionary
        for (key, value) in obj {
            println("Property: \"\(key as! String)\"")
            for (key2, value2) in (value as NSDictionary){
                println("Property: \"\(key2 as! String2)\"")
            }
        }
    }

In your case because the first dictionary is just one key you can retrieve it directly instead use the first for loop:

for item in dataArray { // loop through data items
    let obj = (item.first as! NSDictionary).objectForKey("result") as NSDictionary
    for (key, value) in obj {
        println("Property: \"\(key as! String)\"")
    }
}
Icaro
  • 14,585
  • 6
  • 60
  • 75
  • I see. Let me see how if it works. Also, Is my dual dictionary problem a result of NSURL sessions or did I add an extra line somewhere that made that happen? – petermaxstack Jun 11 '15 at 22:19
  • @petermaxstack no there is nothing wrong in how you converted it, that is just how the data come from. Let me know how the solution worked for you! – Icaro Jun 11 '15 at 22:39
  • It doesn't seem to work. I keep getting 'AnyObject' does not have a member named Generator for the line: for (key, value) in obj.... So essentially I have an object called parseJSON, that I have supposedly in NSDictionary from using the JSONserialization... Then I wrote in the for loop and its stuck. – petermaxstack Jun 11 '15 at 23:18
  • Sorry Json returns a array of anyobject you have to cast it in order to use as a dictionary, I change to code to fix that (it may need little changes as I am in a Windows computer I am doing this code by memory) – Icaro Jun 11 '15 at 23:20
  • So strange, it keeps telling me I can't cast AnyObject as NSDictionary, and crashing right at that code. Also, I feel like the format changed when I use the JSON seralization, the colon ':' becomes a '=' which could be a problem if I want to cast as NSDictionary, right? I also updated the code I have up there! Did I mess up implementing your code? – petermaxstack Jun 11 '15 at 23:52
  • Sorry is because it is an array of dictionary, so we need to get the first item in the array to work, we actually receive a array of dictionaries from dic1 and another array of dictionaries from dic2, we need to get the fist element of this or loop all the elements – Icaro Jun 12 '15 at 00:00
  • So I'm still confused. I want to back up and understand some key concepts. From the code, 'result' is a NSDictionary. And I assigned parseJSON = result[0], but it returns nil. parseJSON = result["result"] returns an optional, of the inner array. Now, I'm stuck at trying to parse result["result"]. It won't let me dig in and do something as simple as parseJSON["color"]. It says it can't subscribe a value AnyObject with an index STRING. – petermaxstack Jun 12 '15 at 02:34
0

Optional (they ? in code) means that the it can be nil. Check Swift Basics

The quotes went away because it's a printout of an NSDictionary which does not print out in a JSON format.

Note: To make things safer since you never know what server can return:

if let dataArray = result["result"] as NSArray{
      //your code
}
Peter Kuhar
  • 606
  • 6
  • 6
  • "result["result"]" returns a dictionary not an array, you may want to update that in your answer :) – Icaro Jun 11 '15 at 22:40