Run pdflatex command in Swift with App Sandbox turned ON - swift

I want to compile a latex file in swift, I am able to compile the file if the application has the App Sandbox OFF.
If I turn App Sandbox ON and try to compile I get the error: "launch path not accessible"
How can I run the pdflatex command to compile the latex file with the App Sandbox turned ON?
Below is the method the I use and it works with App Sandbox turned OFF.
let latexCmd = "/Users/user/Desktop/test/article.tex"
let logText:String = self.runTerminal(command: latexCmd)
func runTerminal(command: String)->String{
let pipe:Pipe = Pipe()
let task:Process = Process()
task.launchPath = "/Library/TeX/texbin/pdflatex"
task.arguments = ["-file-line-error", "-interaction=nonstopmode", "-synctex=1", command]
task.standardOutput = pipe
task.currentDirectoryPath = "/Users/user/Desktop/test"
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
return output!
}

Related

How to launch terminal and pass it a command using Swift

I want to programmatically open a terminal and paste a command into it like "cd /Users/...".
I can start a terminal using this code, but I don't know how to execute command
guard let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.Terminal") else { return }
let path = "/bin"
let configuration = NSWorkspace.OpenConfiguration()
configuration.arguments = \[path\]
NSWorkspace.shared.openApplication(at: url, configuration: configuration, completionHandler: nil)
It is very important to use the sandbox, the Process command is not suitable.
If all you are trying to achieve is to open a terminal on a specific location all you have to do is to use this code:
let pathToOpen = "/Users/admin/Desktop"
let url = URL(string:"terminal://"+pathToOpen)!
NSWorkspace.shared.open(url)
If you are trying just to run a command in terminal and show the output in your app, here is another useful code snippet:
func shell(_ command: String) -> String {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = ["-c", command]
task.launchPath = "/bin/zsh"
task.standardInput = nil
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return output
}
//Usage:
shell("yourCommandHere")
//please note that you are not allowed to use commands that require sudo

Executing python from swift via bash: "can't open file...[Errno 1] Operation not permitted"

I am learning how to make apps for mac, and I am starting with an app to manage my many discord bots. Essentially, the goal is to have many switches to turn bots on and off, which requires executing the python files for the bots, written using discord.py. I read about a PythonKit module for swift, but when I tried to run a discord bot from the files using that, the build continuously failed, so I decided to use the bash shell to excecute the python. Here is my swift code for using bash shell commands:
func shell(_ command: String) -> String {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = ["-c", command]
task.launchPath = "/bin/zsh"
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return output
}func shell(_ command: String) -> String {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = ["-c", command]
task.launchPath = "/bin/zsh"
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return output
}
I then called shell("/usr/local/bin/python3.9 path/to/file.py"), and made it print the output to the console. This was the output:
/usr/local/bin/python3.9: can't open file 'path/to/file.py': [Errno 1] Operation not permitted. I am running this from both AppCode and Xcode, and made sure to give both of those apps full disk access, as well as giving terminal full disk access to be sure. In addition, I tried running /usr/local/bin/python3.9 path/to/file.pyin my terminal, and it works fine. What is happening here? Why can swift not open this file in the bash shell while I can? What do I do to fix it? Let me know if you need more info(if you think PythonKit is the answer, I'll send the build error info from that to debug that process)
Thanks!
Yonatan Vainer was right, turns out sandboxing was on in the entitlements file, so I had to set it to off, which fixed it.

How to show real time result while using terminal command in a swift script

I am using Xcode Project Renamer to rename my Xcode project, after that I used the code below to install pod file.
It's working good but the terminal showing result after pod installed. I want to show result while installing the pod.
#discardableResult
private func shell(_ command: String) -> String {
let task = Process()
task.launchPath = "/bin/bash"
task.arguments = ["-c", command]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
// pipe.fileHandleForReading.readDataToEndOfFile()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
return output
}
let command = shell("pod install")
print(command)
Can someone help please.

executing system_profiler via swift

Wanting to get a details of all installed applications by executing system_profiler SPApplicationsDataType
The snippet given below works just fine in playground, however gives me code signing internal problem: unexpected error from xpc when I try executing it from an application.
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
}
print(shell("system_profiler SPApplicationsDataType"))
P.S Apologies if this is a dumb question, I'm fairly new to swift and xcode technologies :)

Kill process in swift

I am trying to make a Mac application that will automatically close a code designated application running on the OS. I am trying to use killall (like in Terminal). Whenever I try to run the program, I get, "sysctl: unknown oid 'killall'".
Here's my code:
let task = Process()
task.launchPath = "/usr/sbin/sysctl"
///usr/sbin/sysctl
task.arguments = ["killall","iTunes"]
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.launch()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
print(output)
Thanks in advance!
my 2 cents:
You succeed in killing "iTunes" only if You Xcode App will run with SandoBox DISABLED
All examples on stack overflow about Process are misleading as they call "ls" or "echo" that are always executed in system folders.
I'd suggest you first read the man page for sysctl -- it's used to get and set kernel state. Does that sound like something you want?
The path to killall is /usr/bin/killall, which you can find from Terminal:
> which killall
/usr/bin/killall
Here's the full Swift code:
let pipe = Pipe()
let task = Process()
task.launchPath = "/usr/bin/killall"
task.arguments = ["iTunes"]
task.standardOutput = pipe
task.standardError = pipe
task.launch()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
if let output = String(data: data, encoding: .utf8) {
print(output)
}