I'm not a swiftui programmer at all but trying to create a really simple application that runs a .sh
script for me, have tried googling endlessly but can't seem to get it to work. I've also tried running commands from the terminal in swift (since the .sh script just cds into a location and runs a jar).
import SwiftUI
struct ContentView: View {
@State var isRunning = false
var body: some View {
VStack {
HStack {
Button(action: {
let executableURL = URL(fileURLWithPath:"/Users/myname/Desktop/run.sh")
self.isRunning = true
try! Process.run(executableURL,
arguments: [],
terminationHandler: { _ in self.isRunning = false })
}) {
Text("Run")
}.disabled(isRunning)
.padding(.trailing)
}
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I have also ran chmod x run.sh
on the file aswell as disabling sandboxing on the target/app itself
It builds fine, but when the button is pressed you get an error in xCode
Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=4 "The file “run.sh” doesn’t exist." UserInfo={NSFilePath=/Users/myname/Desktop/run.sh}
Even though I am 100% positive that I have that file on the desktop, with the correct extension.
Any ideas?
CodePudding user response:
It is impossible to access the Desktop
path unless the user explicitly chooses to do it, due to sandbox
restrictions of Apple
, which can be found under Signing & Capabilities
but what you could do is you can force the user to choose the script file they want to run or you can place your script to one of the folders defined on File Access
section
with a code like this:
if let path = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first { // or .documentsDirectory
// also use .downloadsDirectory if and only if you allowed `Downloads Folder` on `Signing & Capabilities`
let executableURL = path.appendingPathComponent("new.sh")
self.isRunning = true
try! Process.run(executableURL,
arguments: [],
terminationHandler: { _ in self.isRunning = false })
}
and also you can just use documentsDirectory
like all other apps do. Believe it or not, it is really good for Apple
to do this kind of restrictions because it would be horrible if all the apps would have access to the desktop directory, write/delete and edit all the stuff and dirten the beautiful scene of the desktop, not mentioning the security issues also.