2

I wrote a simple OSx (10.11) application to execute shell commands when a button is pressed. It works when I run it from xcode, but when I export the application via "archive", one of the buttons no longer works. I don't get an error and I don't get any output either. I am using absolute paths so I don't understand why it works in xcode but not as an exported application, Nor do I understand why one button works and the other doesn't.

Here is the main function that I am using the make the shell commands

 func runCommand(path : String, args : [String]) -> (output: [String], error: [String], exitCode: Int32) { var output : [String] = [] var error : [String] = [] let task = NSTask() task.launchPath = path task.arguments = args let outpipe = NSPipe() task.standardOutput = outpipe let errpipe = NSPipe() task.standardError = errpipe task.launch() let outdata = outpipe.fileHandleForReading.readDataToEndOfFile() if var string = String.fromCString(UnsafePointer(outdata.bytes)) { string = string.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet()) output = string.componentsSeparatedByString("\n") } let errdata = errpipe.fileHandleForReading.readDataToEndOfFile() if var string = String.fromCString(UnsafePointer(errdata.bytes)) { string = string.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet()) error = string.componentsSeparatedByString("\n") } //task.waitUntilExit() let status = task.terminationStatus return (output, error, status) } 

and here is the button that works:

 // Check for configurator 2 app installation let (output, error, status) = self.runCommand("/bin/bash", args: ["-c", "/bin/ls", "/Applications/Apple Configurator 2.app"]) 

and here is the button that doesn't:

 // Check if the phone is plugged in and paired let (output, error, status) = self.runCommand("/bin/bash", args: ["-c", "/usr/local/bin/cfgutil", "get", "isPaired"]) 

What is even more strange, I discovered (through sheer frustration) that if I repeatedly click the button that doesn't work, it will sometimes eventually work.

4
  • For a moment I thought maybe I could help you debug this, but you lost me at "I discovered [...] it will sometimes eventually work"... Are you sure about your observations? Commented Mar 10, 2016 at 20:51
  • I am sure about this. I put in an alert message that would show me the output of the commands when the click didn't work and there is no output (""), no error output either Commented Mar 11, 2016 at 23:21
  • 1
    Are all the if var string successfull? Did you try adding else branches? Since you have default values, it could be the reason for the silent failures. Commented Mar 11, 2016 at 23:37
  • Thanks, that was the problem. You should post the answer so you get credit Commented Mar 15, 2016 at 18:27

2 Answers 2

1

Your issue is the result of two things happening together:

  • you return default values

  • you don't specify alternative branches for the control flow

What happens is that it hides potential failures, and leads to code that is very hard to debug, as you experienced.

A possible solution with your existing code is to cover all possible ways, meaning providing else branches to your if var string = String.fromCString(UnsafePointer(errdata.bytes)) conditions, where you will handle errors.

Sign up to request clarification or add additional context in comments.

Comments

0

Thanks to Eric D. I simplified my code and now everything is working.

func runCommand(path : String, args : [String]) -> (output: NSString, error: NSString, exitCode: Int32) { let task = NSTask() task.launchPath = path task.arguments = args let outpipe = NSPipe() task.standardOutput = outpipe let errpipe = NSPipe() task.standardError = errpipe task.launch() let outdata = outpipe.fileHandleForReading.readDataToEndOfFile() let output = NSString(data: outdata, encoding: NSUTF8StringEncoding) let errdata = errpipe.fileHandleForReading.readDataToEndOfFile() let error_output = NSString(data: errdata, encoding: NSUTF8StringEncoding) task.waitUntilExit() let status = task.terminationStatus return (output!, error_output!, status) } 

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.