Load items from a plist

Asked

Viewed 80 times

1

I’m having trouble loading the items from a Property list. Watch my plist: directory.plist à esquerda e Outlets à direita

Here’s my first View Controller:

import UIKit

class Page1: UITableViewController {

var filePath: String?
var employees: [[String: Any]] = []

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.delegate = self
    self.tableView.dataSource = self

    filePath = Bundle.main.path(forResource: "directory", ofType: "plist")
    employees = NSArray(contentsOfFile: filePath!) as! [[String: Any]]

    for item in employees {

        print(item["Name"] as Any)
        print(item.count)
        print(employees.count)
    }
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return employees.count
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? Page2,
        let indexPath = tableView.indexPathForSelectedRow {
        destination.itemSelecionado = employees[indexPath.row]
        tableView .deselectRow(at: indexPath, animated: true)
    }
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
    cell.nameLabel.text = (employees[indexPath.row]["Name"] as! String)
    cell.positionLabel.text = (employees[indexPath.row]["Position"] as! String)

        return cell
    }
}

Here’s my second View Controller:

import UIKit

class Page2: UITableViewController {

var itemSelecionado: [Page1] = []

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.delegate = self
    self.tableView.dataSource = self
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return itemSelecionado.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell2
    cell.emailLabel.text = (itemSelecionado.employees[indexPath.row]["Email"] as! String )
    cell.phoneLabel.text = (itemSelecionado.employees[indexPath.row]["Phone"] as! String? )

    return cell
    }   
}

The Xcode is returning me 3 errors, it’s them:

inserir a descrição da imagem aqui

However, I do not understand why these mistakes, someone could help me?

From now on, thank you!


Problem when trying to insert image: inserir a descrição da imagem aqui

  • Explain exactly what the result you want, because I could see two possibilities, but that would generate different changes.

  • I want an app that presents itself in 2 Tableviews. The first will present the name and function of the employee and, when touching a particular employee, the second will present details of the same, phone, email and other items that I will add later.

2 answers

2


The problem is that you are trying to access an internal property of your Page1 view controller in Viewcontroller Page2. If you need to access a variable globally do the following:

Create a structure to group your "global" (shared) variables and add a static property instance, state your Employees array and other properties there that you find necessary.

struct Shared {
    static var instance = Shared()
    var employees: [Employee] = []
}

Create a structure with a custom init to facilitate the creation of your structures:

struct Employee {
    let position: String
    let name: String
    let email: String
    let phone: String
    init(dictionary: [String: String]) {
        self.position = dictionary["Position"] ?? ""
        self.name = dictionary["Name"] ?? ""
        self.email = dictionary["Email"] ?? ""
        self.phone = dictionary["Phone"] ?? ""
    }
}

So Voce can read the plist inside the didFinishLaunchingWithOptions method in its Appdelegate class:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    if let url = Bundle.main.url(forResource: "directory", withExtension: "plist"), let array = NSArray(contentsOf: url) as? [[String: String]] {
        Shared.instance.employees = array.map{Employee(dictionary: $0)}
    }
    return true
}

And view Employees in any view controller:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        Shared.instance.employees.forEach({
            print("name:", $0.name)
            print("position:", $0.position)
            print("phone:", $0.phone)
            print("email:", $0.email)
            print()
        })
    }
}
  • https://www.dropbox.com/s/h1bzehot1tac1v2/plist%20sample.zip? dl=1

  • 1

    Man, it helped me a lot!! It was exactly what I needed! Thank you very much!! Just one final question: if I change the root from plist to Dictionary, just change the Appdelegate Nsarray to Nsdicitionary?

  • 1

    Yes use Nsarray(contentsOf:) for array and Nsdictionary(contentsOf:) for dictionaries

  • I tried to insert an image into the Employee structure, I did so: Let image: Uiimage ... self.image = Dictionary["image"] ?? "" But he keeps accusing error. Any ideas? Thanks

0

I managed to solve those problems, but now others have appeared. I am not getting the data in my Tableviewcontroller.

I did it this way: first I created a variable to receive Struct Shared:

var item1: Shared!

After defining the numberOfSections and the numberOfRowsInSection, I think I put some incorrect information on dequeueReusableCell. But I don’t know what it was. Look what I did:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
    cell.nameLabel.text = (item1.employees[indexPath.row]["Name"] as? String)
    cell.positionLabel.text = (item1.employees[indexPath.row]["Position"] as? String)

In the last two lines below he informs:

Type 'Employee' has no subscript Members

I couldn’t identify what I put wrong.

  • 1

    You better open another question and I’ll take a look when you’re with Mac in front of me

  • 1

    You do not need instantiate the structure. You will always use the Shared.instance.whatever

  • 1

    http://stackoverflow.com/a/41560949/2303865

  • 1

    cell.nameLabel.text = Shared.instance.employees[indexPath.row].nome

  • 1

    It was just missing I put the .name. I managed to solve everything thanks to you, thank you very much comrade!!

  • 1

    because Voce does not use an array for funcs instead of dictionary?

  • I hadn’t considered, but in this case what I change in App Delegate and Struct?

  • 1

    I switched to the dictionary. If you want to put some image in your dictionary just put the name of the image you have in Asset then just add a property to the image let image: UIImage and initializes inside struct init using self.image = UIImage(named: imageName)

  • 1

    imageNoce puts it somewhere in your plist

  • I edited the question showing the problem that arises in Struct when I try to insert picture.

  • 1

    uses string to initialize Uiimage

  • 1

    self.image = UIImage(named: (dicionary["image"] as? String ?? ""))!

  • 1

    beware of the use of exclamation. Make sure there is an image in your Asset with the name Voce stored in the plist

  • 1

    me passes the images and the updated plist that I fix here what is necessary and update the project and the response

  • I’m getting a little bit here, but until it’s unraveling. How do I tell you? The problem that has arisen now is that in the end I am launching everything in a Tableview, this was no problem, until I have to insert an image inside the Details in the cell... finally, I find it difficult to explain here, without showing.

  • 1

    That’s why you shouldn’t ask questions in the commentary. There is no way to detail enough :) Open another question and follow your step by step

  • 1

    @Leodabus beauty, I will do it more calmly. Anyway, thank you for the strength, comrade!

  • I created: http://answall.com/questions/193091/como-homehomedata

Show 13 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.