Reputation: 6459
I create an os X project and use Main Menu to open file directory and show the contents on tableview.
In my AppDelegate.swift:
class AppDelegate: NSObject, NSApplicationDelegate {
var filePath: String = String() {
didSet {
// Pass filePath to ViewController
}
}
@IBAction func openFile(sender: AnyObject) {
let myOpenDialog = NSOpenPanel()
myOpenDialog.canChooseDirectories = true
if(myOpenDialog.runModal() != 0) {
self.filePath = myOpenDialog.URL!.path!
}
}
My ViewController.swift:
class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
@IBOutlet weak var fileTableView: NSTableView!
private var objects: NSMutableArray! = NSMutableArray()
var fileDirectory: String = String() {
didSet {
showFileList(fileDirectory)
}
}
func showFileList(fileDirectory: String) {
var contentsInFolder: NSArray?
var isDir : ObjCBool = false
// Remove last loaded objects
self.objects.removeAllObjects()
if NSFileManager.defaultManager().fileExistsAtPath(fileDirectory, isDirectory:&isDir) {
if isDir {
contentsInFolder = try! NSFileManager.defaultManager().contentsOfDirectoryAtPath(fileDirectory)
for id in contentsInFolder! {
if ((id as! String).rangeOfString(".MOV") != nil) {
self.objects.addObject(id)
}
}
}
}
self.fileTableView.reloadData()
}
// MARK: - Table View
func numberOfRowsInTableView(tableView: NSTableView) -> Int
{
return self.objects.count
}
}
I got an error "fatal error: unexpectedly found nil while unwrapping an Optional value" when I run the self.fileTableView.reloadData() in ViewController.swift. Any idea how to fix it?
var vc = ViewController()
var filePath: String = String() {
didSet {
vc.fileDirectory = filePath
}
}
Upvotes: 1
Views: 2652
Reputation: 6459
var vc = ViewController()
It will create another instance in AppDelegate and the display UI instance will not get the value pass via this way. I try to use NSNotification and Delegate method and my problem is solved.
AppDelegate.swift
var filePath: String = String() {
didSet {
NSNotificationCenter.defaultCenter().postNotificationName("refreshView", object: nil)
}
}
ViewController.swift
var fileDirectory: String = String()
let delegate = NSApplication.sharedApplication().delegate as! AppDelegate
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "refreshView:", name: "refreshView", object: nil)
}
func refreshView(notification: NSNotification) {
fileDirectory = delegate.filePath
}
By doing so, I can get the filePath from my AppDelegate.swift
Upvotes: 0
Reputation: 1937
When showFileList
is called as part of the initialisation process for ViewController
, the connection between fileTableView
and your UITableView
in the view is not yet set. Therefore, it is nil
when self.fileTableView.reloadData()
is executed.
Simply check for nil
before calling reloadData
:
if(self.fileTableView != nil) self.fileTableView.reloadData()
On a side note, you should probably be doing this for self.objects
as well. I'm guessing that self.objects
is always initialised before self.fileTableView
since it is declared before, but I don't know if it is documented behaviour in the Swift specification(would appreciate if someone who knows about this can chip in).
Upvotes: 0