2012-09-21 4 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

위대한 작품! 감사! –