Llg Llg - 23 days ago 7
JSON Question

Set label from JSONSerialization result

I have a swift application

Swift 3
that interact with the server to get the data. Still now I can successfully be connected to the server. The problem is that when I want to get a specific data from the
JSON
result to set a label text value, I always got the value
Optional(x)
in the console and the label value is always
nil
.

This is the format of my data that I receive from the server:

[A: 1,
B: 2,
C: 3]


And this is how I get it:

let task = session.dataTask(with: request) { data, response, error in

do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary else {
throw JSONError.ConversionFailed
}
self.labelA.text = json[“A”] as? String

} catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}
task.resume()


Edit:
I can also get those formats:

Case 1:

[
{
id: 1,
fieldA: “nameA”,
fieldB: [“textA”, “textB", “textC”, “textD”],
fieldC: “nameC”
}
]


Case 2:

{
id: 1,
fieldA: “nameA”,
fieldB: [“textA”, “textB", “textC”, “textD”],
fieldC: “nameC”
}


The fieldB is an array of String

Answer

First of all never use NSDictionary in Swift unless you have no choice. Use Swift native types.

Second of all the result values in the dictionary seem to be Int rather than String.

...
   guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Int] else {
       throw JSONError.ConversionFailed
   }
   if let jsonA = json["A"] {
       self.labelA.text = "\(jsonA)"
   }

in case the values are String

...
   guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String:String] else {
      throw JSONError.ConversionFailed
   }
   if let jsonA = json["A"] {
      self.labelA.text = jsonA
   }

Case 1 can be parsed with the following code, the nil coalescing operator ?? assigns a default value in case the key does not exist.

   guard let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String:Any]] else {
      throw JSONError.ConversionFailed
   }
   for json in jsonArray {
      let identifier = json["id"] as? Int ?? 0
      let fieldA = json["fieldA"] as? String ?? ""
      let fieldB = json["fieldB"] as? [String] ?? [String]()
      let fieldC = json["fieldC"] as? String ?? ""
  }

Case 2 is a dictionary [String:Any] and the same as case 1 but without the array loop.