1

I want to show plist content into a table view, but Xcode crashed.

This is my code to get plist data :

    var tableData = [String]()

        override func viewDidLoad() {
            super.viewDidLoad()

            self.tblMain.delegate = self
            self.tblMain.dataSource = self


            let path = Bundle.main.path(forResource: "Province", ofType: "plist")!
            let dict = NSDictionary(contentsOfFile: path)

            tableData = dict!.object(forKey: "root") as! [String]
        }


       func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! CountryNameCell
            cell.lblCountryName.text = tableData[indexPath.row]
            return cell
        }

This is my plist file :

enter image description here

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • post the crash . – Shehata Gamal Oct 08 '19 at 12:03
  • Fatal error: Unexpectedly found nil while unwrapping an Optional value . on this line : tableData = dict!.object(forKey: "root") as! [String] – mehran kmlf Oct 08 '19 at 12:05
  • dict is maybe empty, check in debugger. Better do this: if let dict = dict { tableData = dict.object(forKey: "root") as? [String] } else { print error here } – Chris Oct 08 '19 at 12:09
  • 1
    Answer is posted in this topic https://stackoverflow.com/questions/24045570/how-do-i-get-a-plist-as-a-dictionary-in-swift. https://stackoverflow.com/a/24045628/9048325 – Vladyslav Shmatok Oct 08 '19 at 12:10

2 Answers2

1

You need

let path = Bundle.main.path(forResource: "Province", ofType: "plist")! 
tableData  = NSArray(contentsOfFile: path) as! [String]
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
0

The root object is an array, there is no key root (not even with uppercase R).

In Swift you are discouraged from using the NSArray/NSDictionary API to read and write property lists. The highly recommended API is PropertyListSerialization

let url = Bundle.main.url(forResource: "Province", withExtension: "plist")!
do {
    let data = try Data(contentsOf: url)
    tableData = try PropertyListSerialization.propertyList(from: data, format: nil) as! [String]
} catch {
    print(error)
}

You can even remove the do - catch block and try! reading the data as the file is in the application bundle which cannot be modified at runtime. A crash reveals a design mistake which can be fixed instantly.

vadian
  • 274,689
  • 30
  • 353
  • 361