2

システム プロファイラから情報を読み取ってみてください。この目的のために、NSTask でいくつかのターミナル ライン コマンドを実行しています。出力が大きすぎないコマンドを実行しても問題はありません (例: SPInstallHistoryDataType)。しかし、「SPApplicationsDataType」コマンドを実行してインストール済みアプリケーションのリストを収集すると、NSTask が待機しすぎて、結果もエラーも発生しません。

それで、バッファサイズなどがあるはずだと思い始めましたが、それについて何も見つかりませんでした。私は多分私が間違った道を進んでいるのかわからない。

func readData (dataType: String) -> NSArray? {
let out = NSPipe()
let task = NSTask()
task.launchPath = "/usr/sbin/system_profiler"
task.arguments = ["-xml",dataType]
task.standardOutput = out
task.launch()

task.waitUntilExit()

if task.terminationStatus != 0 {
    NSLog("system_profiler returned error status")
    return nil
}

let data = out.fileHandleForReading.readDataToEndOfFile()
let plist : AnyObject?
do {
    plist = try NSPropertyListSerialization.propertyListWithData(data,
        options: [.Immutable],
        format: nil)
} catch let error as NSError {
    NSLog("%@", "Failed to parse system_profiler results. \(error.localizedDescription)")
    return nil
}

return plist as? NSArray
}
let r = readData("SPInstallHistoryDataType")// There is no problem
let r2 = readData("SPApplicationsDataType") // Crash

注:はい、このデータをファイルに書き込んで、そのファイルから読み取ることができました。しかし、私は何が問題なのかを理解しようとしています。

4

2 に答える 2

5

それは間違いなくバッファの問題です。一度にチャンクを読み取ると、機能します。

func getApplications() -> String?
{
    var retval=""
    let theTask = NSTask()
    let taskOutput = NSPipe()
    theTask.launchPath = "/usr/sbin/system_profiler"
    theTask.standardOutput = taskOutput
    theTask.standardError = taskOutput
    theTask.arguments = ["-xml", "SPApplicationsDataType"]
    theTask.launch()

    while (true) {
        let data = taskOutput.fileHandleForReading.readDataOfLength(1024)
        if (data.length <= 0) { break }
        let str = String(data: data, encoding: NSUTF8StringEncoding)!
        retval += str

        //print (str)
    }

    theTask.waitUntilExit()

    return retval
}
于 2016-03-14T00:36:12.510 に答える