Alan
Alan

Reputation: 305

Store values from a JSON file into variables

I've been trying for hours to read values from a JSON file in the app bundle and print those values. I've been scouring several forums and SO questions trying to piece together a way to read from a .json file, but have had no luck. What I currently have is a bunch of (probably useless) code that looks like this:

//json parsing
        if let path = Bundle.main.path(forResource: "POIs", ofType: "json") {
            do {
                let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
                let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
                if let jsonResult = jsonResult as? Dictionary<String, AnyObject>, let pois = jsonResult["POI"] {

                    print("test ", pois)
                    for poi in pois as! [AnyObject] {
                        guard let name = poi["name"], //String
                            let coordinatesJSON = poi["coordinates"] as? [String: Double],
                            let latitudeVar = coordinatesJSON["lat"],
                            let longitudeVar = coordinatesJSON["lng"],
                            let altitude = poi["altitude"], //Int
                            let facebookurl = poi["facebookurl"], //String
                            let poiImage = poi["pinImage"] //String
                        else {
                            return
                        }

and my POIs.json file looks like this:

{
"POI":[
        {
            "name": "Boston Paintball",
            "coordinates": {
                "lat": 42.401848,
                "lng": -71.023843
            },
            "altitude": 7,
            "facebookurl": "https://www.facebook.com/PlayBostonPaintball/",
            "pinImage": "bp"
        },
        {
            "name": "Chilis",
            "coordinates": {
                "lat": 42.402314,
                "lng": -71.021655
            },
            "altitude": 7,
            "facebookurl": "https://www.facebook.com/chilis",
            "pinImage": "chilis"
        }
    ]
}

Can anyone show me the best way to read values from a json, store them into the variables I specified, and then print them? Thank you!

UPDATED CODE:

//json parsing
        let file = Bundle.main.url(forResource: "POIs", withExtension: "json")
        let data = try? Data(contentsOf: file!)
        let root = try? JSONDecoder().decode(Root.self, from: data!)

        do {
            let root = try JSONDecoder().decode(Root.self, from: data!)
            print(root)
        } catch {
            print(error)
        }

        let decoder = JSONDecoder()
        let pois = try? decoder.decode([Root].self, from: data!)

        let pinUIImage = UIImage(named: Location.pinImage)

But still giving me a Instance member 'pinImage' cannot be used on type 'ViewController.Location' error.

UPDATE 2:

for poi in (root?.pointsOfInterest)! {
            if let location = root?.pointsOfInterest.??? { //I dont know how to grab the poi from the current iteration. Any tips?

Upvotes: 1

Views: 226

Answers (1)

Leo Dabus
Leo Dabus

Reputation: 236370

You should structure your data to conform to Codable protocol:

struct Root: Codable {
    let pointsOfInterest: [Location]
    private enum CodingKeys: String, CodingKey {
        case pointsOfInterest = "POI"
    }
}
struct Location: Codable {
    let name: String
    let coordinates: Coordinate
    let altitude: Int
    let facebookurl: String
    let pinImage: String
}
struct Coordinate: Codable {
    let latitude: Double
    let longitude: Double
    private enum CodingKeys: String, CodingKey {
        case latitude = "lat", longitude = "lng"
    }
}

do {
    let root = try JSONDecoder().decode(Root.self, from: jsonData)
    print(root)
} catch {
    print(error)
}

This will print

Root(pointsOfInterest: [__lldb_expr_39.Location(name: "Boston Paintball", coordinates: __lldb_expr_39.Coordinate(latitude: 42.401848000000001, longitude: -71.023842999999999), altitude: 7, facebookurl: "https://www.facebook.com/PlayBostonPaintball/", pinImage: "bp"), __lldb_expr_39.Location(name: "Chilis", coordinates: __lldb_expr_39.Coordinate(latitude: 42.402313999999997, longitude: -71.021654999999996), altitude: 7, facebookurl: "https://www.facebook.com/chilis", pinImage: "chilis")])

Upvotes: 1

Related Questions