The NSOpenSavePanelDelegate `validate` delegate method does not receive permission to the selected directory/file in sandboxed app

Number:rdar://46998451 Date Originated:02-Jan-2019 11:51 AM
Status:Open Resolved:
Product:macOS + SDK Product Version:macOS 10.14.2
Classification:Other Bug Reproducible:Always
I use `NSOpenPanel` to let the user select a directory where my app can output some files. I want to inform the user early, while the open panel is still open, if the user tries to select a read-only directory, as I wouldn't be able to write to that. The problem is that the `validate` delegate method doesn't get access to the user-selected directory, so it will always show the error message for all directories, even writable ones.

Steps to Reproduce:
I have this code to open the panel:

final class AppDelegate: NSObject, NSApplicationDelegate {
	func convert() {
		let panel = NSOpenPanel()
		panel.delegate = self
		panel.canChooseFiles = false
		panel.canChooseDirectories = true
		panel.canCreateDirectories = true
		panel.allowsMultipleSelection = false
		panel.prompt = "Convert"
		panel.message = "Choose where to save the converted images"

		panel.beginSheetModal(for: window) {
			if $0 == .OK {
				self.startConversion(urls, outputDirectory: panel.urls.first!)

And I have implemented the `validate` delegate method to show an error while the open panel is shown, which informs the user that the directory they chose is read-only:

extension AppDelegate: NSOpenSavePanelDelegate {
	func panel(_ sender: Any, validate url: URL) throws {
		if !FileManager.default.isWritableFile(atPath: url.path) {
			throw CocoaError(.fileWriteVolumeReadOnly)

Expected Results:
I expected `FileManager.default.isWritableFile(atPath: url.path)` to return `true` for a path that is writable.

Actual Results:
The code `FileManager.default.isWritableFile(atPath: url.path)` always returns `false` because it doesn't get access to the security scoped bookmark created by `NSOpenPanel`.

macOS 10.14.2

The workaround is to just let the user select anything, then in `panel.beginSheetModal`, check whether the directory writable, and if not, show an NSAlert and then show the `NSOpenPanel` again. This is a bad user-experience.


Stack Overflow question

By sindresorhus at Jan. 2, 2019, 11:27 a.m. (reply...)

Related Radar

By sindresorhus at Jan. 2, 2019, 11:26 a.m. (reply...)

Twitter thread

By sindresorhus at Jan. 2, 2019, 11:23 a.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!