-1

Issue getting secondary data to display in my UITableView. I have 3 pieces of data coming back from the API - Name, Address, Telephone. No issues getting "Name" to display, but when I try to display the secondary data (address, telephone) I am stuck. I have two code files here, a ViewController File that is handling the TableView and a Model file that handles the data parsing. The secondary data is referred to as "detailedTextLabel" in my code. Any help greatly appreciated!

First Code File is ViewController - Second is Model file.

import UIKit

struct SportsItem {
    let facility: String
    let address: String
    let telephone: String
}

class SportsResultsViewController: UIViewController, UITableViewDataSource {
    var sportsData: [SportsItem] = []
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sportsData.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath)
       
        cell.textLabel?.text = sportsData[indexPath.row].facility
        cell.detailTextLabel?.numberOfLines = 0
        cell.detailTextLabel?.text = "Address: \(sportsData[indexPath.row].address)\nPhone: \(sportsData[indexPath.row].telephone)"
        
        cell.textLabel?.font = UIFont.systemFont(ofSize: 8)
        cell.detailTextLabel?.font = UIFont.systemFont(ofSize: 8)
        
        return cell
    }
    
    var jsonString: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        resultsTableView.dataSource = self
        resultsTableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
        resultsTableView.cellLayoutMarginsFollowReadableWidth = true
        resultsTableView.rowHeight = UITableView.automaticDimension
        resultsTableView.estimatedRowHeight = 164.0
        
        
        
        if let jsonString = jsonString {
            if let data = jsonString.data(using: .utf8),
               let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
               let features = json["features"] as? [[String: Any]] {
                
                var sportsData: [SportsItem] = []
                
                for i in 0..<min(10, features.count) {
                    if let feature = features[i]["properties"] as? [String: Any]? ?? [:],
                       let address = feature["Address"] as? String,
                       let telephone = feature["Telephone"] as? String,
                       let facility = feature["Facility Name"] as? String {
                        
                        let sportsItem = SportsItem(facility: facility, address: address, telephone: telephone)
                        sportsData.append(sportsItem)
                    }
                }
                
                self.sportsData = sportsData
                
                if sportsData.isEmpty {
                    // Handle empty data case if needed
                }
                
                resultsTableView.reloadData()
            }
        }
    }
    


    @IBAction func findHotelsPressed(_ sender: UIButton) {
        UIApplication.shared.open(URL(string: "https://www.hotels.com/de606379/hotels-hong-kong-hong-kong-sar/")!)
    }
    
    @IBOutlet weak var resultsTableView: UITableView!
    
    
    
}

Second Code File (DataModel File)...

import UIKit

struct SportsManager {
    let sportsURL = "https://geodata.gov.hk/gs/api/v1.0.0/geoDataQuery?q=%7Bv%3A%221%2E0%2E0%22%2Cid%3A%22d1a2e8e0-8636-41e9-b664-0e64b86860a2%22%2Clang%3A%22ALL%22%7D"
    
    func getSportsData(completion: @escaping (String?) -> Void) {
        guard let url = URL(string: sportsURL) else { return }
        
        URLSession.shared.dataTask(with: url) { (data, response, error) in
            if let error = error {
                print(error.localizedDescription)
                completion(nil)
                return
            }
            
            guard let data = data else {
                completion(nil)
                return
            }
            
            do {
                let jsonData = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
                let jsonString = try JSONSerialization.data(withJSONObject: jsonData ?? "", options: .prettyPrinted)
                let sportsData = String(data: jsonString, encoding: .utf8)
                completion(sportsData)
            } catch let error {
                print(error.localizedDescription)
                completion(nil)
            }
        }.resume()
    }
}

The address line doesn't appear in the table cells:

Simulator View

HangarRash
  • 7,314
  • 5
  • 5
  • 32
macdevmike
  • 11
  • 2
  • What's the question? – matt Jun 16 '23 at 03:02
  • The issue I am having is that the secondary data is not displaying. It should be displaying...the code seems correct. But the "address" or "telephone" data is not displaying – macdevmike Jun 17 '23 at 11:35

1 Answers1

1

The problem is that a cell's detailTextLabel is only valid if the cell is created with a style other than .default. In your case you want cells to be created with a style of .subtitle.

You have two possible solutions. One is to fix your code, the other is to update your storyboard correctly.

Code-only:

  1. Remove the line:

    resultsTableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
    
  2. Replace the line:

    let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath)
    

    with the line:

    let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) ?? UITableViewCell(style: .subtitle, reuseIdentifier: "CellIdentifier")
    

That's it. You should now see both lines of text in each cell.


Storyboard:

Since you have created the table view in a storyboard (based on it being an outlet), you really should do all of the table and cell setup in the storyboard. It makes little sense to add the table view via storyboard and outlet but then use code to set it up. Connect the table's data source and delegate outlets in the storyboard. Setup the prototype cell in the storyboard. In your case, set the cell's Style to "Subtitle" and set the Identifier to "CellIdentifier".


Also note that the old style table cell setup using textLabel and detailTextLabel has been deprecated since iOS 14. Unless you need to support iOS 13, you should be either creating your own custom cell with the desired content or use the new content configuration APIs.

HangarRash
  • 7,314
  • 5
  • 5
  • 32