Reputation: 11
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:
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.
Upvotes: 1
Views: 1768
Reputation: 83
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.
Upvotes: 1
Reputation: 3526
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)
Upvotes: 3