How to get json array from json object in SWIFT? - json

Hello friends I need your help for reading the array from the json object.
like
{"info":[{"memoID":"3","memoName":"Hello"}]}
using SwiftyJSON
when I'm in android I can use
JSONArray array = object.getJSONArray(“info”);

JSONDecoder
let content = try? JSONDecoder().decode(Root.self , from: data)
print(content)
// MARK: - Empty
struct Root: Codable {
let info: [Info]
}
// MARK: - Info
struct Info: Codable {
let memoID, memoName: String
}
SwiftyJson
if let res = arr["info"].array { // arr is of type JSON
print(res)
}

Related

Parse Json to nested Struct using Swift

I am trying to parse a JSON that I am receiving in my Application. The JSON Syntax is correct but I am unable to parse it into a nested Struct.
Here is my code that can be run in Playground:
let message = "{\"type\":\"something\",\"data\":{\"one\":\"first\",\"two\":\"second\",\"three\":\"third\"}}"
let jsonData = message.data(using: .utf8)!
struct Message: Decodable {
let type: String
struct data: Decodable {
var one: String
var two: String
var three: String
}
}
let receivedMessage: Message = try! JSONDecoder().decode(Message.self, from: jsonData)
The printed Result is Message(type: "something") but the data is not parsed.
How can I parse the data correctly to use it afterwards.
The nested struct/dictionary is the value for key data
struct Message: Decodable {
let type: String
let data: Nested
struct Nested: Decodable {
var one: String
var two: String
var three: String
}
}

I can't decode a JSON file in Swift, even so I could read it into a Data object

I'm quite new in Swift. I created a simple terminal app inside Xcode to learn about decoding JSON files. Even so I was able to read the file into a Data object, I couldn't decode it for my struct:
Here is my struct:
struct Person: Codable
{
var name: String
var surname: String
}
Here is my simple JSON file:
[
{
"name": "Abc",
"surname": "Def"
}
]
And here is my Swift code to decode the JSON file:
let url = URL(fileURLWithPath: "/Users/abcd/Documents/test.json")
if let data = try? Data(contentsOf: url)
{
print(data) // prints size (in bytes) the data correctly
if let person = try? JSONDecoder().decode(Person.self, from: data)
{
print(person) // did not printed
}
}
The JSON contains an array. Accordindly, you should use one in your code as well:
if let persons = try? JSONDecoder().decode([Person].self, from: data)
...

Trying to parse json, can't seem to parse arrays inside of an array

I've been trying to parse a part of this JSON file: https://opendata.brussels.be/api/records/1.0/search/?dataset=traffic-volume&rows=3&facet=level_of_service
I wanna get records->fields->geo_shape->coordinates but I can't seem to print these arrays inside of the "coordinates" array.. I thought it might be because the arrays inside of the coordinates do not have names, so I don't know how to make a variable for them. Got this code currently:
import UIKit
import Foundation
struct Geoshape : Codable {
let coordinates: Array<...>
}
struct Field : Codable {
let geo_shape: Geoshape
let level_of_service: String
}
struct Record: Codable {
let fields: Field
}
struct Traffic: Codable{
let records: Array<Record>
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func clickRefresh(_ sender: Any) {
guard let url = URL(string: "https://opendata.brussels.be/api/records/1.0/search/?dataset=traffic-volume&rows=3&facet=level_of_service") else { return }
let session = URLSession.shared
let task = session.dataTask(with: url){ (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
let traffic = try? JSONDecoder().decode(Traffic.self, from: data)
print(traffic)
}
}
task.resume()
}
}
Clearly the Array<...> needs to be changed but I don't know to what. I've tried making an extra struct with just 1 variable (which is another array of the type Double: Double) but that does not seem to work. I was able to print everything just fine up to the point I tried to go into the coordinates array.
Anyone can help me?
Replace
let coordinates: Array<...>
with
let coordinates:[[Double]]
First of all your file in Resource contains a JSON which contains an array or Collection (typically in Swift).
One important thing: If you fail to decode an object in json you get null from all stored properties.
fail occurs when your Coding Keys does not match keys in json or type you are casting is diffrent.
In your code you fail to cast coordinates to its type. coordinates is a collection of collections of Double.
var coordinates: [[Double]]
If you want to fetch data into your models, you should conforms them to Decodable protocol which means that,JSON attributes can decode itself.
Based on Apple developer documentation:
Decodable is a type that can decode itself from an external representation.
also Codable protocol refers to Decodable and Encodable protocols. but current purpose is Decoding data.
typealias Codable = Decodable & Encodable
Your code should look like:
Swift 5
Prepared for Playground, paste this into your playground
import Foundation
struct GeoShape: Decodable {
var coordinates: [[Double]]
}
struct Field: Decodable {
var geo_shape: GeoShape
}
struct Record: Decodable {
var fields: Field
}
struct Traffic: Decodable {
var records: [Record]
}
guard let url = URL.init(string: "https://opendata.brussels.be/api/records/1.0/search/?dataset=traffic-volume&rows=3&facet=level_of_service")
else {fatalError()}
URLSession.shared.dataTask(with: url){ (data, response, error) in
if let data = data {
let traffic = try? JSONDecoder().decode(Traffic.self, from: data)
print("First coordinate is: ",traffic?.records.first?.fields.geo_shape.coordinates.first)
}
}.resume()

Swift - Using Decodable to decode JSON array of just strings

I have a sample JSON where its just an array of strings and has no keys and would like to use the Decodable protocol to consume the JSON and create a simple model out of it.
The json looks like this:
{ "names": [ "Bob", "Alice", "Sarah"] }
Just a collection of strings in an simple array.
What I'm unsure about is how do I use the new Swift Decodable protocol to read this into a model without a key.
Most of the examples I've seen assume the JSON has a key.
IE:
// code from: Medium article: https://medium.com/#nimjea/json-parsing-in-swift-2498099b78f
struct User: Codable{
var userId: Int
var id: Int
var title: String
var completed: Bool
}
do {
//here dataResponse received from a network request
let decoder = JSONDecoder()
let model = try decoder.decode([User].self, from:
dataResponse) //Decode JSON Response Data
print(model)
} catch let parsingError {
print("Error", parsingError)
}
This above example assumes that the json is a key-value; how can I use the decodable protocol to de-code the JSON without keys?
With thanks
The corresponding struct of this JSON is
struct User: Decodable {
let names: [String]
}
and decode
let model = try decoder.decode(User.self, from: dataResponse)
and get the names with
let names = model.names
or traditionally without the overhead of JSONDecoder
let model = try JSONSerialization.jsonObject(with: dataResponse) as? [String:[String]]
For this simple structure of json , i guess it's better not to create any structs and use
let model = try decoder.decode([String:[String]].self, from: dataResponse)
print(model["names"])
the json fiting for your model is
{
"names": [{
"userId": 2,
"id": 23,
"title": "gdgg",
"completed": true
}]
}
struct Root: Codable {
let names: [User]
}
struct User: Codable {
let userId, id: Int
let title: String
let completed: Bool
}

how to convert JSON dictionary to string value in swift 4

I'm new to Swift and I started working on a Swift 4 project with a PHP server.
I use Alamofire for requests, and print the data using print(). This is is what i'm getting:
{"error":false,"n":"Raghad"}
But when I want to convert it to String, it returns "" (empty) and
when I convert to boolean it returns the value correctly.
So, how can I fix it?
let wJSON : JSON = JSON(response.result.value!)
print(wJSON["n"].stringValue)
print(wJSON["error"].boolValue)
Simple solution using Decodable, define a Struct that conforms to the Decodable protocol for your dictionary
struct Reply: Decodable {
let error: Bool
let n: String
}
let data = response.data
do {
let result = try JSONDecoder().decode(Reply.self, from: data)
print("\(result.n) \(result.error)")
} catch {
print(error)
}
I change the responseString to responseJSON
Alamofire.request(Url!, method: .post, parameters: par).validate().responseJSON { response in if response.result.isSuccess { let wJSON : JSON = JSON(response.result.value!)
and it's work