rb2030
rb2030

Reputation: 439

Turning JSON file into an array in Swift/Xcode

I have been struggling all week. I am new to programming. I cannot turn a simple JSON file into a dictionary in Xcode. There is little simplified documentation online using the new method of Codable. So I am using a walkthrough, which has the following code.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let path = Bundle.main.path(forResource: "menu", ofType: "json") else { return }
        let url = URL(fileURLWithPath: path)

        do {

            let data = try Data(contentsOf: url)
            let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
            //print(json)

            guard let array = json as? [Any] else { return }
            for user in array {
                guard let userDict = user as? [String: Any] else { return }
                guard let drinks = userDict["drinks"] as? String else { print("not a String"); return }
                guard let junkFood = userDict["junk-food"] as? String else { return }

                print(drinks)
                print(junkFood)
                print(" ")
            }
        }
        catch {
            print(error)
        }

    }

}

The below code is what my JSON looks like.

{"menu": {
  "drinks": [
    {"coke": "20"},
    {"pepsi": "20"},
    {"water": "20"}
  ],
  "junk-food": [
    {"hamburger": "40"},
    {"fries": "20"},
    {"pizza": "20"}
  ]
}}

Can anyone please walk me through, or show me some simplified documentation as to how I can turn the JSON into a dictionary that I can later map the data from? I am using Xcode and trying to work out Swift 4.

Thanks in advance for your patience.

Upvotes: 0

Views: 886

Answers (1)

erdos
erdos

Reputation: 662

My guess is that your json is actually a Dictionary not an Array. So guard let array = json as? [Any] else { return } is falling through because the json is [String: Any]. You can get to the array with the "menu" key.

Here's an updated version of your code:

 do {
        let data = try Data(contentsOf: url)
        let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
        //print(json)

        guard let menuDict = json as? [String: Any] else { return }

        guard let drinks = menuDict["drinks"] as? [[String: Any]] else { 
            print("not an array of dictionaries") 
            return 
        }

        guard let junkFood = menuDict["junk-food"] as? [[String: Any]] else { 
            print("not an array of dictionaries") 
            return 
        }
        print(drinks)
        print(junkFood)
        print(" ")
    }

Try that, let me know if it works. This is just the do block by the way.

Upvotes: 1

Related Questions