skip to Main Content

I am trying to run command lines to take screenshots in my Xcode project and using Pipe() to log output data.
When I build and run this project in Xcode, I can get the output information as a string, like this screenshot’s basic information. But when I archive this project as a MacOS applicaiton and run it, I get an error. I can’t get any information for outputData.

The result of "outpipe.fileHandleForReading.readDataToEndOfFile()" is empty.

Here are my codes:

let task = Process()
task.launchPath = "/usr/sbin/screencapture"
var arguments = [String]();
arguments.append("-s") 
let ScreenshotPath = "screenshotpath.jpg"
arguments.append(ScreenshotPath)
task.arguments = arguments

let outpipe = Pipe()
task.standardOutput = outpipe
task.standardError = outpipe

do {
    try task.run()
} catch {
    print("error in process")
}
let outputData = outpipe.fileHandleForReading.readDataToEndOfFile()
let resultInformation = String(data: outputData, encoding: .utf8)
task.waitUntilExit()
print(resultInformation)

Can somebody help me with this out? Thank you so much!

2

Answers


  1. I believe the issue is assigning your Pipe object to both task.standardOutput and task.standardError. I recommend creating two distinct Pipe objects, then passing them to the outputs respectively.

    We used the function from this answer in production on the Mac App Store.

    Login or Signup to reply.
  2. The main issue is that you are trying to read from your file before any output is captured and written to disk.

    The ‘-s’ option specifies mouse selection mode, which is interactive. Trying running it from the command line as:

    screenshot -s screenshot.jpg

    You should end up seeing some large crosshairs with x and y coordinates.

    The output file isn’t written in this case until you finish your selection.

    The other problem is that you are trying to read the contents of the file without knowing if it is actually complete. You could use the terminationHandler of the completion block as in:

    task.terminationHandler = {
        let outputData = outpipe.fileHandleForReading.readDataToEndOfFile()
        let resultInformation = String(data: outputData, encoding: .utf8)        
    }
    

    This will ensure you read the file after it’s actually written. Hope that helps.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search