0

I am trying to loop through a JSON array which I am getting from an HTTP Request, but I am not sure how.

What I have tried is this:

var request = NSMutableURLRequest(url: url! as URL, cachePolicy: NSURLRequest.CachePolicy.returnCacheDataElseLoad, timeoutInterval: Double.infinity)
if Reachability.isConnectedToNetwork(){
    request = NSMutableURLRequest(url: url! as URL, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: Double.infinity);
}
let session = URLSession.shared
var getResp = false

var zinnen : [Zin] = []
let task = session.dataTask(with: request as URLRequest,
                            completionHandler: { data, response, error -> Void in
                                let json = try? JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]
                                for case let data in json {
                                    if let zin = Zin(json: data) {
                                        zinnen.append(zin)
                                    }
                                }
})
task.resume()

And this is my struct:

struct Zin : CustomStringConvertible {
    var description: String

    let id : Int
    let dutch_sentence : String
    let polish_sentence : String
    init(dictionary: [String: Any]) {
        self.id = dictionary["id"] as? Int ?? 0
        self.dutch_sentence = dictionary["dutch_sentence"] as? String ?? ""
        self.polish_sentence = dictionary["polish_sentence"] as? String ?? ""
    }
}

A sample of the JSON Array:

[  
   {  
      "id":"35",
      "dutch_sentence":"Ja",
      "polish_sentence":"Tak"
   },
   {  
      "id":"36",
      "dutch_sentence":"Nee",
      "polish_sentence":"Nie"
   }
]

But in this I get the error

Type '[String: Any]??' does not conform to protocol 'Sequence'

4
  • let json = try? JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] => let json = try? JSONSerialization.jsonObject(with: data!, options: []) as? [[String: Any]] You JSON is an Array of Dictionaries, not a Dictionary so the for loop is weird for a dictionary. Commented Dec 14, 2017 at 12:49
  • use the codable protocol instead of parsing the JSON manually. see benscheirman.com/2017/06/swift-json Commented Dec 14, 2017 at 13:13
  • @Larme That changed my error from Type '[String: Any]??' does not conform to protocol 'Sequence' to Type '[[String: Any]]??' does not conform to protocol 'Sequence' Commented Dec 14, 2017 at 13:19
  • Thanks @Scriptable I will look in to it Commented Dec 14, 2017 at 13:19

1 Answer 1

1

Don't ignore the error! Both try? and optional downcast cause a nested optional (Optional<Optional<[String:Any]>>) which of course is not a sequence, not even when being casted to an array.

Handle the error, optional bind the result and cast the result to the more specified array [[String:String]]. According to the JSON the value for id is String not Int.

do {
   if let json = try JSONSerialization.jsonObject(with: data!) as? [[String: String]] {
      for zinData in json {
          let zin = Zin(dictionary: zinData)
          zinnen.append(zin)
      }
   }
} catch { print(error) }

PS: The initializer in the Zin class does not match the initializer in the parsing code. I'm using the version of the class. You have to change the type of id from Int to String

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

2 Comments

Thank you this solved the problem! And you are right I was thinking because it's a number I should use it but it's a string in the JSON.
Reading JSON is very easy and straightforward. Every value in double quotes is a string, period. There are no exceptions.

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.