Load a UIViewController with data from .plist

315 views Asked by At

I have a UITableView set up in storyboard with static rows populated with different content, and all going to a single UIViewController. I've also got a separate plist for each view I intend to load (containing the different content), that I would like loaded depending on which row was selected.

As a bonus, I would rather have a single plist that the UITableViewController will populate the rows with (instead of having 120+ static rows in storyboard), but am unsure of how to do that as well.

I've searched quite a bit, but only found things for Objective-C. I'm a bit new to Swift, and never really got far into Objective-C, but I think I've got the basics down.

Right, my question. My question is, how can I load each individual plist (one for each row) and display its contents when the UIViewController is shown? My bonus question is: how can I consolidate my 120+ static rows into a single plist that basically accomplishes the same thing, except instead of editing the SB to add new rows, I just need to add to the plist?

1

There are 1 answers

0
Wingzero On BEST ANSWER

First of all, it's rare to use plist to store such contents. Not easy to maintain. Use XML or json to store it are better choices.

Regards your question #1,

put below code to a loop to load your plist into a dict like this:

let path = NSBundle.mainBundle().pathForResource("Your_path", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path!)

You may want to store all the dicts into an array, so you know how many plists you have. Let's say we have dictArray property in your view controller to hold all your dicts.

You don't add static cell on SB for UITableView, it's not efficient. You just let the dataSource delegate to load the data and create as many cells as it needs.

I will leave some code for you to write, this will warm you up. I just give the essential part of code.

Don't forget to set your dataSource and delegate to proper object, like self!

then,

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as UITableViewCell

    let row = indexPath.row
    let dictOfPlist = self.dictArray[row]

    // now you get your plist while configuring your cells,
    // do your customization for your cells from now on

    return cell
}

// MARK:  UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let row = indexPath.row
    let dictOfPlist = self.dictArray[row]

    // if you tap one cell, now you get its corresponding plist
    // time to pass the data to your view controller
    // either use segue or other ways to do it
    }
}

Some ways to pass data to your new UIViewController:

If you segue exist in the storyboard with a segue identifier between your 2 views, you can just call it programmatically using:

performSegueWithIdentifier("mySegueID", sender: yourDataDict)

later you can access yourDataDict in your nextViewController to load it

You could also do :

nextViewController.dataDict = yourDataDict // set a public property so you can access it later on

presentViewController(nextViewController, animated: true, completion: nil)

Or if you are in a Navigation controller :

self.navigationController?.pushViewController(nextViewController, animated: true)

To consolidate your plists into one plist, you might need to write some small programs or scripts to merge them; or copy them. There's a quite a lot of ways to do it. But as I suggested, I don't recommend you to continue using plist to do such things. You better change to another form at beginning. Otherwise when you realize you really need to change, it's too late and you have many code to rewrite.