Swift – Detailed instruction on use of NSOpenPanel

swift

I want to be able to open an image in Swift. This is my first Swift project.

@IBAction func SelectFileToOpen(sender: NSMenuItem) {
    var openPanel = NSOpenPanel();
    openPanel.allowsMultipleSelection = false;
    openPanel.canChooseDirectories = false;
    openPanel.canCreateDirectories = false;
    openPanel.canChooseFiles = true;
    let i = openPanel.runModal();
    if(i == NSOKButton){
        print(openPanel.URL);
        var lettersPic = NSImage(contentsOfURL: openPanel.URL!);
        imageView.image = lettersPic;

    }
}

Output of my NSLog when using the open panel

Optional(file:///Users/ethansanford/Desktop/BigWriting.png)
fatal error: unexpectedly found nil while unwrapping an Optional value

How can I allow the user to open a png file of interest.
When I specifying the same file in the code everything works well. An example of me indicating which file to open in the code without using the open file panel and acting as a user:

let pictureURl = NSURL(fileURLWithPath: "///Users/ethansanford/Desktop/BigWriting.png");
var lettersPic = NSImage(contentsOfURL: pictureURl!);
imageView.image = lettersPic; 

Is there a problem with the format of my URL or something? Any help would be appreciated.

Best Solution

Add a new file to your project (swift source file) and add this extension there

Xcode 9 • Swift 4

extension NSOpenPanel {
    var selectUrl: URL? {
        title = "Select Image"
        allowsMultipleSelection = false
        canChooseDirectories = false
        canChooseFiles = true
        canCreateDirectories = false
        allowedFileTypes = ["jpg","png","pdf","pct", "bmp", "tiff"]  // to allow only images, just comment out this line to allow any file type to be selected 
        return runModal() == .OK ? urls.first : nil
    }
    var selectUrls: [URL]? {
        title = "Select Images"
        allowsMultipleSelection = true
        canChooseDirectories = false
        canChooseFiles = true
        canCreateDirectories = false
        allowedFileTypes = ["jpg","png","pdf","pct", "bmp", "tiff"]  // to allow only images, just comment out this line to allow any file type to be selected
        return runModal() == .OK ? urls : nil
    }
}

In your View Controller:

class ViewController: NSViewController {
    @IBOutlet weak var imageView: NSImageView!
    @IBAction func saveDocument(_ sender: NSMenuItem) {
        print("SAVE")
    }
    @IBAction func newDocument(_ sender: NSMenuItem) {
        print("NEW")
    }
    // connect your view controller to the first responder window adding the openDocument method
    @IBAction func openDocument(_ sender: NSMenuItem) {
        print("openDocument ViewController")
        if let url = NSOpenPanel().selectUrl {
            imageView.image = NSImage(contentsOf: url)
            print("file selected:", url.path)
        } else {
            print("file selection was canceled")
        }
    }
}
Related Question