2012-09-21 71 views
0

我似乎無法監控我的NSTask命令的輸出。據我瞭解,必須使用NSNotificationCenter。我嘗試運行的終端命令使用各種加密方法從我的安全服務器上下載文件(在objective-c中重寫此操作將是一個很大的麻煩)。我將需要監視結果,以便我可以收到已完成下載的百分比。NSTask實時監控輸出

這裏是我迄今爲止

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]; 

} 

請注意:下載開始,沒有踏進我的第二個方法的進展。但是,下載完成並且進程結束後,應用程序崩潰。

回答

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; 
} 
+0

很好用!謝謝! –