我编写了一个简单的OSx(10.11)应用程序,用于在按下按钮时执行shell命令。当我从xcode运行它时它可以工作,但是当我通过" archive"导出应用程序时,其中一个按钮不再有效。我没有收到错误,也没有收到任何输出。我使用的是绝对路径,所以我不明白为什么它在xcode中工作但不能作为导出的应用程序工作,我也不明白为什么一个按钮工作而另一个按钮不工作。
这是我使用make shell命令的主要功能
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)
}
这是一个有效的按钮:
// Check for configurator 2 app installation
let (output, error, status) = self.runCommand("/bin/bash", args: ["-c", "/bin/ls", "/Applications/Apple Configurator 2.app"])
这里是没有按钮的按钮:
// 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"])
更奇怪的是,我发现(通过纯粹的挫折感)如果我反复点击不起作用的按钮,它有时最终会起作用。
答案 0 :(得分:1)
你的问题是两件事发生在一起的结果:
您返回默认值
您没有为控制流指定替代分支
它会隐藏潜在的失败,导致代码很难调试,就像您所经历的那样。
现有代码的可能解决方案是涵盖所有可能的方式,即在else
条件中提供if var string = String.fromCString(UnsafePointer(errdata.bytes))
分支,您将处理错误。
答案 1 :(得分:0)
感谢Eric D.我简化了我的代码,现在一切正常。
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)
}