title: Swift Plist Reading and Initializing Arrays as Objects for Key
body: <p>I'm developing a small <code>UITableView</code>-based app in Swift. I started out hard-coding some basic arrays as such (included is the basic class declaration and the <code>UITableView</code> outlet declaration:</p>
  
  <pre><code>import UIKit
  
  class ScenesViewController: UITableViewController {
  
  @IBOutlet var myTableView: UITableView
  
  var sceneName = ["Scene 1", "Scene 2", "Scene 3", "Scene 4", "Scene 5"]
  var sceneDetail = ["Hi", "Hello", "Bye", "My Bad", "Happy"]
  </code></pre>
  
  <p>This code is inside a <code>UITableViewController</code> which has an outlet that is all hooked up to a <code>UITableView</code>. I have created a plist for this called "Scenes.plist" and have attempted to replace the code. In Objective-C, I would do this:</p>
  
  <pre><code>NSString *path = [[NSBundle mainBundle] pathForResource:@"Scenes" ofType:@"plist"];
  
  NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
  sceneName = [dict objectForKey:@"SceneName"];
  sceneDetail = [dict objectForKey:@"SceneDetail"];
  </code></pre>
  
  <p>I started doing this in Swift like this:</p>
  
  <pre><code>let path = NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist")
  
  let dict = NSDictionary(contentsOfFile:path)  // Error: 'ScenesViewController.Type' does not have a member named 'path'
  </code></pre>
  
  <p>I scoured the Internet for a solution but was unable to find one. So I took up the next course of action - an 'almost' one-liner:</p>
  
  <pre><code>let dict = NSDictionary(contentsOfFile: 
      NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist"))
  
  var sceneName = dict["SceneName"] // Error: 'ScenesViewController.Type' does not have a member named 'dict'
  </code></pre>
  
  <p>Now, the only solution I can almost resort to is having all of that on one line for each array:</p>
  
  <pre><code>var sceneName = NSDictionary(contentsOfFile: 
      NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist").objectForKey("SceneName")
  // Warning: Variable 'sceneName' inferred to have type 'AnyObject!', which may be unexpected
  // Fix-It: Add an explicit type annotation to silence this warning (var sceneName: AnyObject! = ...)
  </code></pre>
  
  <p>So I added the explicit type annotation just to find out that there were more errors. Inside the <code>cellForRowAtIndexPath:</code> function:</p>
  
  <pre><code>override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -&gt; UITableViewCell? {
      let cell: UITableViewCell = tableView!.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell
  
      // Configure the cell...
  
      cell.textLabel.text = sceneName[indexPath!.row] // Error: could not find member 'row'
      return cell
  }
  </code></pre>
  
  <p>There are actually <strong>two errors</strong>; I do not know whether this is accidentally duplicated or not. The next error(s) are in the the <code>prepareForSegue:sender:</code> method:</p>
  
  <pre><code>override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
      if segue?.identifier == "ShowDetails" {
          var detailVC: ScenesDetailViewController = segue!.destinationViewController as ScenesDetailViewController
  
          var myIndexPath: NSIndexPath = myTableView.indexPathForSelectedRow()
  
          var row: Int = myIndexPath.row
  
          detailVC.detailModal = [sceneDetail[row], sceneName[row]] // Error: Could not find an overload for 'subscript' that accepts the supplied arguments
      }
  }
  </code></pre>
  
  <p>Again, there are two errors; however, I believe this is because <code>sceneDetail</code> and <code>sceneName</code> are both used. There seem to be errors all over the place with reading and using plists in files that aren't there (or that I haven't come across) in Objective-C.</p>