繁体   English   中英

当从 xcode 运行时,使用 NSTask 的 Swift 2.1 OSx shell 命令工作,但在导出时不起作用

[英]Swift 2.1 OSx shell commands using NSTask work when run from xcode, but not when exported

我编写了一个简单的 OSx (10.11) 应用程序来在按下按钮时执行 shell 命令。 当我从 xcode 运行它时它可以工作,但是当我通过“归档”导出应用程序时,其中一个按钮不再起作用。 我没有收到错误,也没有得到任何输出。 我使用的是绝对路径,所以我不明白为什么它在 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"])

更奇怪的是,我发现(完全出于沮丧)如果我反复单击不起作用的按钮,它有时最终会起作用。

您的问题是两件事情同时发生的结果:

  • 你返回默认值

  • 您没有为控制流指定替代分支

发生的情况是它隐藏了潜在的故障,并导致代码很难调试,正如您所经历的那样。

您现有代码的一个可能解决方案是涵盖所有可能的方式,这意味着为您的if var string = String.fromCString(UnsafePointer(errdata.bytes))条件提供else分支,您将在其中处理错误。

感谢 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)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM