AppKit’s NSOpenPanel
class can display the standard macOS file open dialog. In addition to selecting files to open, the open file dialog gives Sandboxed apps access to specified directories on the file system.
This article explains how to use AppKit’s NSOpenPanel
class.
Run the open file dialog
The NSOpenPanel
class is a type of window that inherits from the NSWindow
class. You can execute a file open dialog by following the steps below.
- Configure dialog settings.
- Run as the modal dialog with the
runModal
method. - Get the selected items.
Set selectable file types
Use the following property to set the selectable file types.
var allowedContentTypes: [UTType] { get set }
Specify the selectable file types in an array of UTIs to the allowedContentsTypes
property. For example, if JPEG and PNG files are selectable, the code is as follows.
let openPanel = NSOpenPanel()
openPanel.allowedContentTypes = [.jpeg, .png]
However, this property is only available on macOS 11 or later. Set the following property to an array of extensions on earlier OSs.
var allowedFilesTypes: [String]? { get set }
Given this property is marked as Deprecated in macOS 12.0, it’s more appropriate to adapt its usage depending on the operating system.
let openPanel = NSOpenPanel()
if #available(macOS 11.0, *) {
openPanel.allowedContentTypes = [.jpeg, .png]
} else {
openPanel.allowedFileTypes = ["jpg", "png"]
}
Run as a modal dialog
The runModal
method allows you to run the open file dialog as a modal dialog.
func runModal() -> NSApplication.ModalResponse
.OK
is returned when the “Open” button is clicked, and .cancel
is returned when the “Cancel” button is clicked. The application determines the return value as follows.
func selectFile() {
let openPanel = NSOpenPanel()
if #available(macOS 11.0, *) {
openPanel.allowedContentTypes = [.jpeg, .png]
} else {
openPanel.allowedFileTypes = ["jpg", "png"]
}
let modalResponse = openPanel.runModal()
if modalResponse == .OK {
}
}
Get the selected files
The selected file will be stored in the following property.
var urls: [URL] { get }
For example, the following code outputs the selected file to the console.
func selectFile() {
let openPanel = NSOpenPanel()
if #available(macOS 11.0, *) {
openPanel.allowedContentTypes = [.jpeg, .png]
} else {
openPanel.allowedFileTypes = ["jpg", "png"]
}
let modalResponse = openPanel.runModal()
if modalResponse == .OK {
openFiles(urls: openPanel.urls)
}
}
func openFiles(urls: [URL]) {
for url in urls {
print("\(url)")
}
}
Set default directory
You can assign the following property to set the default directory of the open file dialog.
var directoryURL: URL? { get set }
For example, the following code initially navigates to the “Pictures” folder in the open file dialog.
openPanel.directoryURL = try! FileManager.default.url(for: .picturesDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
How to select a directory
Set the following property to true
to allow selecting the directory.
var canChooseDirectories: Bool { get set }
Also, setting the following property to false
will disable file selection.
var canChooseFiles: Bool { get set }
By setting the values of these two properties, you can make only directories selectable or both files and directories selectable.
How to select multiple files
NSOpenPanel
allows only one file to be selected by default. Still, multiple files can be selected by setting the following property to true
.
var allowsMultipleSelection: Bool { get set }
For example,
func selectFile() {
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = true
openPanel.directoryURL = try! FileManager.default.url(for: .picturesDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
if #available(macOS 11.0, *) {
openPanel.allowedContentTypes = [.jpeg, .png]
} else {
openPanel.allowedFileTypes = ["jpg", "png"]
}
let modalResponse = openPanel.runModal()
if modalResponse == .OK {
openFiles(urls: openPanel.urls)
}
}
func openFiles(urls: [URL]) {
for url in urls {
print("\(url)")
}
}
Sandbox Entitlement Settings
In the case of a sandboxed app, only files, directories, and subdirectories selected by the user in the file open dialog are allowed to be read or written. Therefore, the app must implement the behavior of displaying the dialog and having the user select the file. You must also configure the entitlement accordingly.
Open the app’s target settings, go to the “Signing & Capabilities” tab, and in the “File Access” setting in “App Sandbox”, set the following items.
Type | Description |
---|---|
User Selected File | Access rights for the item selected in the file open dialog. |
Downloads Folder | Download folder access rights. |
Pictures Folder | Picture folder access rights. |
Music Folder | Music folder access rights |
Movies Folder | Movie folder access rights |
There are three types of access rights.
Permission & Access | Description |
---|---|
None | No access rights |
Read Only | Read only |
Read/Write | Read/Write |