1

I'm writing an app that displays a list of PDF files in a NSTableView that the user should be able to double-click to open in the default application (Preview, Adobe Reader, ...).

I've tried using NSWorkspace.shared.openFile and NSWorkspace.shared.open(_: withAppBundleIdentifier: options: additionalEventParamDescriptor: launchIdentifiers:), but none of them work.

I can't use the new func open(URL, configuration: NSWorkspace.OpenConfiguration, completionHandler: ((NSRunningApplication?, Error?) -> Void)?) as this is targeted at pre-Catalina computers.

Here are the two code snippets:

1.

@objc func doubleClickOnResultRow() { let clickedRow = resultsTableView.selectedRow if ( clickedRow > -1 ) { let myURL = foundItems[clickedRow] as URL if (!NSWorkspace.shared.openFile(myURL.path)) { print("Unable to open : ", myURL.path) } } } 

This first one does nothing, and I get a "Unable to open : url/to/my/file.pdf" in the console.

2.

@objc func doubleClickOnResultRow() { let clickedRow = resultsTableView.selectedRow if ( clickedRow > -1 ) { let myURL = foundItems[clickedRow] as URL NSWorkspace.shared.open([myURL], withAppBundleIdentifier: "com.apple.Preview", options: NSWorkspace.LaunchOptions.withErrorPresentation, additionalEventParamDescriptor: nil, launchIdentifiers: nil) } } 

With this one, however, when I double-click on a file, I get a error window with the Finder icon that says :

"The application “My app” does not have permission to open “myfile.pdf.” Here is the screenshot:

Finder error

I don't understand what I'm doing wrong. Eventually I could build a lightweight PDF viewer inside my app, but I would really like to avoid it if possible.

EDIT 03/31/2020, 16:10

I've tried a third way, by calling the shell command "open" with this (found here):

func shell(_ command: String) -> String { let task = Process() task.launchPath = "/bin/bash" task.arguments = ["-c", command] let pipe = Pipe() task.standardOutput = pipe task.launch() let data = pipe.fileHandleForReading.readDataToEndOfFile() let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String return output } 

and then

let command = "open \""+myURL.path+"\"" print(shell(command)) 

and I get

LSOpenURLsWithRole() failed with error -54 for the file path/to/my/file.pdf. 
1

2 Answers 2

3

You have to construct the URL to file using init(fileURLWithPath:) of URL not the usual init?(string:)

let url = URL(fileURLWithPath: "/path/to/file.pdf") 

Then you can open it with default application using NSWorkspace.open instance method

NSWorkspace.shared.open(url) 
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer. I get exactly the same error window that with my 2nd code snippet.
1

enter image description here

According to LSOpenURLsWithRole() failed with error -54 for the file path/to/my/file.pdf.
This is because your app does not have the permission to access other file.
You should do the following things to resolve.
1,find the entitlements file.
2,set the "App Sandbox" key to NO.
3,then you can open the file successfully.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.