我似乎无法监视 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];
}
请注意:下载开始并继续进行,而无需进入我的第二种方法。但是,应用程序在下载完成且进程结束后崩溃。
最佳答案
-(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;
}
关于iphone - NSTask实时监控输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12525099/