I've been digging for an answer for a long time but I never get to a working code.
I have a code that uses dd to generate a file. Sometimes it takes a few minutes depending on the size and I thought it would be great to have a progress bar. So far everything works and is tied up. The progress bar, however, doesn't update because I need to constantly send values to it. I found a way to get the current value, I managed to get pv to display the current data, but now I can't get the output in real time inside the application, except in the log.
So far, this is the best I got to:
// Action:
// dd if=/dev/zero bs=1048576 count=500 |pv -Wn -s <size>|of=/Users/me/Desktop/asd.img
// Be careful, it generates files of 500MB!!
NSTask * d1Task = [[NSTask alloc] init];
NSTask * pvTask = [[NSTask alloc] init];
NSTask * d2Task = [[NSTask alloc] init];
[d1Task setLaunchPath:@"/bin/dd"];
[pvTask setLaunchPath:@"/Users/me/Desktop/pv"];
[d2Task setLaunchPath:@"/bin/dd"];
// For pvTask I use something like...
// [[NSBundle mainBundle] pathForAuxiliaryExecutable: @"pv"]
// ... in the final version.
[d1Task setArguments: [NSArray arrayWithObjects:
@"if=/dev/zero"
, @"bs=1048576"
, @"count=500"
, nil]];
[pvTask setArguments:[NSArray arrayWithObjects:
@"-Wn"
, [ NSString stringWithFormat:@"-s %d", 1048576 * 500]
, nil]];
[d2Task setArguments: [NSArray arrayWithObjects:
@"of=/Users/me/Desktop/file.dmg"
, nil]];
NSPipe * pipeBetween1 = [NSPipe pipe];
[d1Task setStandardOutput: pipeBetween1];
[pvTask setStandardInput: pipeBetween1];
NSPipe * pipeBetween2 = [NSPipe pipe];
[pvTask setStandardOutput: pipeBetween2];
[d2Task setStandardInput: pipeBetween2];
// Missing code here
[d1Task launch];
[pvTask launch];
[d2Task launch];
In the missing code part, I tried several things. First I tried an observer, like this:
NSFileHandle * pvOutput = [pipeBetween2 fileHandleForReading];
[pvOutput readInBackgroundAndNotify];
[ [NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(outputData:)
name:NSFileHandleDataAvailableNotification
object:pvOutput
];
No success. I get feedback only in the beginning or the end of the execution, but still no feedbacks during it.
I also tried something like:
[pvOutput setReadabilityHandler:^(NSFileHandle *file) {
// Stuff here
}];
But there is no such method here. Maybe my XCode is outdated? (I use 4.2).
Lately I've been trying the same generic code using /sbin/ping pinging 10 times a server, but no success getting the output. How can I do this? Any documents I can read about this subject?
Thanks!