How do I output this json into a UITableView & UILabels

How do I output this json into a UITableView & UILabels? Please approach these separately. I believe this will solve all my networking issues for this project:

"fields": {
        "brandName": {
            "stringValue": "brandName"
        },
        "unit": {
            "stringValue": "3050"
        },
        "street": {
            "stringValue": "St. Daphne Dr."
        },
        "postalCode": {
            "stringValue": "63301"
        },
        "city": {
            "stringValue": "St. Charles"
        },
        "state": {
            "stringValue": "MO"
        },
        "country": {
            "stringValue": "USA"
        },
        "instructions": {
            "stringValue": "Hello! I am a text field!"
        }
    }
}

I have this model that works but I can’t get the delegate and datasource to network properly for the TableView:

// MARK: - DeliveryOffer
struct DeliveryOffer: Codable {
    let fields: Fields
}

// MARK: - Fields
struct Fields: Codable {
    let brandName, unit, street, postalCode, city, state, country, instructions: BusinessInfo
    
}

// MARK: - BrandName
struct BusinessInfo: Codable {
    let stringValue: String
}

What do you have so far as your delegate and data source?

What isn’t showing up specifically?

I was following this tutorial and I was stumped on how to use my model that does not use arrays to fit what is going on in this tutorial. Hope this makes sense:

https://youtu.be/g0kOJk4hTnY

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
   

    var deliveryOffer: DeliveryOffer?
    
    private var tableView: UITableView = {
        let table = UITableView(frame: .zero, style: .grouped)
        table.register(UITableView.self, forCellReuseIdentifier: "cell")
        return table
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
       parseJSON()
        view.addSubview(tableView)
        tableView.delegate = self
        tableView.dataSource = self

    }
    
//    var results = [Fields(brandName: BusinessInfo(stringValue: "brandName"), unit: BusinessInfo(stringValue: "unit"), street: BusinessInfo(stringValue: "street"), postalCode: BusinessInfo(stringValue: "postalCode"), city: BusinessInfo(stringValue: "city"), state: BusinessInfo(stringValue: "state"), country: BusinessInfo(stringValue: "country"), instructions: BusinessInfo(stringValue: "instructions"))]
    
//    init(deliveryOffer: DeliveryOffer? = nil, tableView: UITableView, results: [Fields] = [Fields(brandName: BusinessInfo(stringValue: "brandName"), unit: BusinessInfo(stringValue: "unit"), street: BusinessInfo(stringValue: "street"), postalCode: BusinessInfo(stringValue: "postalCode"), city: BusinessInfo(stringValue: "city"), state: BusinessInfo(stringValue: "state"), country: BusinessInfo(stringValue: "country"), instructions: BusinessInfo(stringValue: "instructions"))]) {
//        self.deliveryOffer = deliveryOffer
//        self.tableView = tableView
//        self.results = results
//    }
//
//    required init?(coder: NSCoder) {
//        fatalError("init(coder:) has not been implemented")
//    }
    
    // TableView
    func numberOfSections(in tableView: UITableView) -> Int {
        <#code#>
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        <#code#>
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        <#code#>
    }
    
    
    
    
   // JSON
    private func parseJSON() {
        // Make a path to the data.json file.
        guard let path = Bundle.main.path(forResource: "data", ofType: "json") else {
            return } // forResource: is the file name, ofType: is the file extention
            // Pass in the path which is a string
            let url = URL(fileURLWithPath: path)
//            var deliveryOffer: DeliveryOffer? // For testing
            // Access the content of the URL and it is throw, so put it in a do-catch method and try
            do {
                let jsonData = try Data(contentsOf: url)
                deliveryOffer = try JSONDecoder().decode(DeliveryOffer.self, from: jsonData)
                
                
                 // For testing
                if let deliveryOffer = deliveryOffer {
                    print(deliveryOffer)
                }
                else {
                    print("Failed to parse")
                }
                return
            }
            catch {
                print("Error: \(error)")
            }
    }

}

// MARK: - DeliveryOffer
struct DeliveryOffer: Codable {
    let fields: Fields
}

// MARK: - Fields
struct Fields: Codable {
    let brandName, unit, street, postalCode, city, state, country, instructions: BusinessInfo
    
}

// MARK: - BrandName
struct BusinessInfo: Codable {
    let stringValue: String
}

The parts that I commented-out are just my attempt to create an array model that could possibly work with my JSON without messing with the JSON tree.

TableViews are used to enable arrays of data to be displayed. In this case your json is not an array so what kind of a layout were you expecting to achieve using a tableView?

That’s interesting. So, When I’m presented with JSON that doesn’t give an array, I must use different approach?

In this case would the use of UILabels be appropriate? …what do you recommend?

Hi @coder3000

Also I think the JSON you shared is invalid.

1 Like

@Joash,

There is a missing opening brace at the top. Should be like this:

{
    "fields": {
        "brandName": {
            "stringValue": "brandName"
        },
        "unit": {
            "stringValue": "3050"
        },
        "street": {
            "stringValue": "St. Daphne Dr."
        },
        "postalCode": {
            "stringValue": "63301"
        },
        "city": {
            "stringValue": "St. Charles"
        },
        "state": {
            "stringValue": "MO"
        },
        "country": {
            "stringValue": "USA"
        },
        "instructions": {
            "stringValue": "Hello! I am a text field!"
        }
    }
}
1 Like

Yes, just decode the json into deliveryOffer and then extract the relevant properties and populate UILabels in your View.

Got it to work! Thanks!

Now,… I am working with the data.json file to which holds the “DeliveryOffer”. I will have other pages like “Pickup” and "Dropoff. What is the approach to having multiple JSON trees? Can data.json hold them all? If so could you show me an example of how to separate them without getting an error in the model?

Should this question be on a new thread?

It’s best to create a new thread since the original question has been answered.

1 Like