1

I'm new to Swift and JSON and am having trouble. I have looked at all sorts of Q&A's here and tried incorporating the advice, but am failing to do so correctly.

I have the server generating JSON which is ok according to a JSON lint checker (http://jsonlint.com).

Using a browser, the response is this:

[{"PostalCode":"NW4 2JL"},{"PostalCode":"NW4 2ES"},{"PostalCode":"NW4 3XP"},{"PostalCode":"NW4 4DU"},{"PostalCode":"NW4 2HH"},{"PostalCode":"NW4 2DR"},{"PostalCode":"NW4 2DX"}]

Xcode, however, gives me this error:

Error, sorry, could not parse JSON: Optional([{"PostalCode":"NW4 2JL"},{"PostalCode":"NW4 2ES"},{"PostalCode":"NW4 3XP"},{"PostalCode":"NW4 4DU"},{"PostalCode":"NW4 2HH"},{"PostalCode":"NW4 2DR"},{"PostalCode":"NW4 2DX"}])

What baffles me, and I can find no explanation for, is the 'Optional()' part. Prior to that, the error statement is as I wrote it, on line 12 (the only message that includes the word 'sorry'). The JSON inside the '()' looks fine.

Can anyone advise what I've done wrong here, or at least where the 'Optional()' text is coming from?

This is the relevant portion of my code:

   let task = session.dataTaskWithRequest(request) { data, response, error in
        guard data != nil else {
            print("no data found: \(error)")
            return
        }
        do {
            if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as? NSDictionary {
                let success = json["success"] as? Int
                print("Success: \(success)")
            } else {
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Error, sorry, could not parse JSON: \(jsonStr)")
            }
        } catch let parseError {
            print(parseError)
            let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
            print("Error could not parse JSON: '\(jsonStr)'")
        }
    }
Denis
  • 25
  • 4
  • @Eric D: optionals could be transitory too, I suppose they are there for back compatibiliy reasons, not because they are smart –  Apr 05 '16 at 14:42
  • @IanBell Optionals are a key concept in Swift, Chris Lattner has said this numerous times. They're not going anywhere soon. :) – Eric Aya Apr 05 '16 at 14:45
  • Wow this site is good. As soon as I posted this, I found the answer elsewhere (http://stackoverflow.com/questions/8356842/how-to-use-nsjsonserialization). Really sorry. The solution was to use NSArray instead of NSDictionary, since, well, the response was an Array. – Denis Apr 05 '16 at 14:46
  • Thanks, I will do so. – Denis Apr 05 '16 at 14:48
  • @Eric D: I must admit I really don't like them, so I'm voting for them to disappear as soon as possible :-) –  Apr 05 '16 at 15:02

1 Answers1

0

With this line:

let success = json["success"] as? Int

you're making success an Optional. And since optionals conform to the protocol CustomStringConvertible, you get "Optional(...)" as a string.

If you don't know yet what is an Optional, stop everything and go learn about it. Now. ;)

Done? Ok, now safely unwrap the optional with, for example, optional binding:

if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
    if let success = json["success"] as? Int {
        print("Success: \(success)")
    }
}

That's it.

Note that here we're accessing a dictionary, but in your question the JSON is an array of dictionaries: it's a bit unclear what you actually have.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253