cs4alhaider
cs4alhaider

Reputation: 1446

Running terminal commands in in cocoa app

I facing a problem when running my code on cocoa app to run some command line scripts

This function run smoothly when using Command line tool but when using full cocoa app with some On Off UI it not working at all

enter image description here My script should turn on/off the http & https proxy

enter image description here

Here is my function:

    private func runTask(_ cmd: String) {

        // Create a Task instance
        let task = Process()

        // Set the task parameters
        task.launchPath = "/bin/sh"
        task.arguments = ["-c", String(format:"%@", cmd)]

        // Create a Pipe and make the task
        // put all the output there
        let pipe = Pipe()
        task.standardOutput = pipe

        // Launch the task
        task.launch()

        // Get the data
        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        guard let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { return }

        print(output)
    }

And here is my full ViewController class:

import Cocoa

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    @IBAction func onButtonTapped(_ sender: NSButton) {
        print("onButtonTapped")
        let selected: Switch = .on
        let listOfNetworkCommands: String = [
            #"networksetup -setwebproxystate "Wi-fi" \#(selected)"#, // switch http proxy
            #"networksetup -setsecurewebproxystate "Wi-fi" \#(selected)"#, // switch https proxy
            #"networksetup -setpassiveftp "Wi-fi" \#(selected)"# // switch passive ftp
            ].joined(separator: " && ")

        runTask(listOfNetworkCommands)
    }

    @IBAction func offButtonTapped(_ sender: NSButton) {
        print("onButtonTapped")
        let selected: Switch = .off
        let listOfNetworkCommands: String = [
            #"networksetup -setwebproxystate "Wi-fi" \#(selected)"#, // switch http proxy
            #"networksetup -setsecurewebproxystate "Wi-fi" \#(selected)"#, // switch https proxy
            #"networksetup -setpassiveftp "Wi-fi" \#(selected)"# // switch passive ftp
            ].joined(separator: " && ")

        runTask(listOfNetworkCommands)
    }

    enum Switch: String {
        case on, off
    }

    private func runTask(_ cmd: String) {

        // Create a Task instance
        let task = Process()

        // Set the task parameters
        task.launchPath = "/bin/sh"
        task.arguments = ["-c", String(format:"%@", cmd)]

        // Create a Pipe and make the task
        // put all the output there
        let pipe = Pipe()
        task.standardOutput = pipe

        // Launch the task
        task.launch()

        // Get the data
        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        guard let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { return }

        print(output)
    }

}

Any idea why my function not triggered in the cocoa app?

Upvotes: 1

Views: 519

Answers (1)

Lucas Derraugh
Lucas Derraugh

Reputation: 7049

Simple answer is found by disabling App Sandbox in your Cocoa Application (found under your Project app target > Capabilities tab > App Sandbox switch). You'll find that you're being blocked by a sandbox exception. Disabling sandboxing should fix your issue.

You can also see this in Console.app if you filter for your app name or the sandboxd process. You'll likely have an entry like this when sandboxing is enabled:

error 00:21:57.502273 +0000 sandboxd Sandbox: sh(17363) deny(1) file-read-data /dev/ttys003

Upvotes: 1

Related Questions