我似乎无法监视我的NSTask命令的输出。据我了解,必须使用NSNotificationCenter。我试图运行的终端命令使用各种加密方法从我的安全服务器下载文件(在objective-c中重写这将是一个很大的痛苦)。我将需要监控结果,以便我可以收到完成下载的百分比。
这是我到目前为止所拥有的
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
task = [[NSTask alloc] init];
pipe = [[NSPipe alloc] init];
NSDictionary *defaultEnvironment = [[NSProcessInfo processInfo] environment];
NSMutableDictionary *environment = [[NSMutableDictionary alloc] initWithDictionary:defaultEnvironment];
[environment setObject:@"YES" forKey:@"NSUnbufferedIO"];
[task setEnvironment:environment];
[task setLaunchPath:[[NSBundle mainBundle] pathForResource:@"servDecryptor" ofType:nil]];
[task setArguments:[NSArray arrayWithArray:arguments]];
[task setStandardOutput:pipe];
fh = [pipe fileHandleForReading];
[nc addObserver:self
selector:@selector(ready:)
name:NSFileHandleReadCompletionNotification
object:fh];
[nc addObserver:self
selector:@selector(decFinished:)
name:NSTaskDidTerminateNotification
object:task];
[task launch];
[fh readInBackgroundAndNotify];
和
//Ready method
[[pipe fileHandleForReading] readInBackgroundAndNotify];
NSData *d;
d = [[note userInfo] valueForKey:NSFileHandleNotificationDataItem];
if ([d length] > 0) {
NSString *s = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding];
}
请注意:下载开始并继续进行而不会进入我的第二种方法。但是,在下载完成并且该过程结束后,应用程序崩溃。
答案 0 :(得分:2)
-(void)uploadData
{
setenv([@"PASSWORD" UTF8String], [mPassword UTF8String], 1);
[task setLaunchPath:executablePathRoot];
[task setArguments:array];
NSPipe *pipe = [NSPipe pipe];
NSPipe *errorPipe = [NSPipe pipe];
[task setStandardOutput:pipe];
[task setStandardError:errorPipe];
//keeps your log where it belongs
//[task setStandardInput:[NSPipe pipe]];
NSFileHandle *outFile = [pipe fileHandleForReading];
NSFileHandle *errFile = [errorPipe fileHandleForReading];
[task launch];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(terminated:)
name:NSTaskDidTerminateNotification
object:task];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(outData:)
name:NSFileHandleDataAvailableNotification
object:outFile];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(errData:)
name:NSFileHandleDataAvailableNotification
object:errFile];
[outFile waitForDataInBackgroundAndNotify];
[errFile waitForDataInBackgroundAndNotify];
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
while(!terminated)
{
if (![[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
{
break;
}
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
[pool release];
[self appendDataFrom:outFile to:output];
[self appendDataFrom:errFile to:error];
//[task waitUntilExit];
[task release];
}
-(void) outData: (NSNotification *) notification
{
NSLog(@"outData");
NSFileHandle *fileHandle = (NSFileHandle*) [notification object];
[self appendDataFrom:fileHandle to:output];
[fileHandle waitForDataInBackgroundAndNotify]; //Checks to see if data is available in a background thread.
}
-(void) errData: (NSNotification *) notification
{
NSLog(@"errData");
NSFileHandle *fileHandle = (NSFileHandle*) [notification object];
[self appendDataFrom:fileHandle to:output];
[fileHandle waitForDataInBackgroundAndNotify];
}
- (void) terminated: (NSNotification *)notification
{
NSLog(@"Task terminated");
[[NSNotificationCenter defaultCenter] removeObserver:self];
terminated =YES;
}