2012-10-27 3 views
0

나는 objective-C가 처음인데 무언가를 놓친다면 용서해주세요. 그러나 우리 모두는 어딘가에서 시작해야합니다 :)NSTask 데이터를 개행으로 나누어서 n

나는 명령을 실행하고 다른 방법으로 결과를 전달하는 또 다른 오픈 소스 프로젝트에서 얻은 코드 스 니펫을 가지고 있습니다. 내가해야 할 일은 stdout에 출력 된 각각의 새로운 라인을 듣고 각 라인으로 무엇인가를하는 것이다.

내가 함께 일하고 있어요 코드 조각은 다음

NSMutableArray *args = [NSMutableArray array]; 

    NSString *input = [details valueForKey:@"input"]; 

    for (NSString *i in [input componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]) { 
     [args addObject:i]; 
    } 

    NSTask *scriptTask = [NSTask new]; 
    NSPipe *outputPipe = [NSPipe pipe]; 

    if ([_NSFileManager() isExecutableFileAtPath:scriptPath] == NO) { 
     NSArray *chmodArguments = @[@"+x", scriptPath]; 

     NSTask *chmod = [NSTask launchedTaskWithLaunchPath:@"/bin/chmod" arguments:chmodArguments]; 

     [chmod waitUntilExit]; 
    } 

    [scriptTask setStandardOutput:outputPipe]; 
    [scriptTask setLaunchPath:scriptPath]; 
    [scriptTask setArguments:args]; 

    NSFileHandle *filehandle = [outputPipe fileHandleForReading]; 

    [scriptTask launch]; 
    [scriptTask waitUntilExit]; 

    NSData *outputData = [filehandle readDataToEndOfFile]; 

    NSString *outputString = [NSString stringWithData:outputData encoding:NSUTF8StringEncoding]; 

    if (NSObjectIsNotEmpty(outputString)) { 
     [self.world.iomt inputText:outputString command:IRCPrivateCommandIndex("privmsg")]; 
    } 

그래서, 오히려 결과 뭔가를하고 다음 프로세스가 완료 될 때까지 기다리지 않고, 내가 도착 각각의 새로운 라인을 기다릴 필요 명령에 의해 표준 출력으로 인쇄됩니다.

내 배경은 대부분 웹 dev에있는, 그래서 당신은 Node.js를 사용하고 있던 이벤트가 방출기 경우 내 목표는 다음과 유사 것 같아요

task = new Task("ls"); 

task.addListener("newline", function(data) { 
    somethingElse("sendmsg", data); 
}); 

task.run(); 

는 희망 당신은 내가으로 묶는거야 이해 이루다. 감사!

답변

0

NSFileHandle에 관찰자를 추가하면 내용을 읽을 때 알려줍니다.

예 :

[fileHandler readInBackgroundAndNotify]; 
//Need to set NSTask output pipes 
[self.task setStandardOutput: outputPipe]; 
[self.task setStandardError: outputPipe]; 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readFromTask:) name:NSFileHandleReadCompletionNotification object:fileHandler]; 

-(void)readFromTask:(NSNotification *)aNotifcation; 
    { 
     NSData *data = [[aNotifcation userInfo] objectForKey: NSFileHandleNotificationDataItem]; 
     if (data != 0) { 
      NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

       // Do something with the text 

      [text release]; 
      [[aNotifcation object] readInBackgroundAndNotify]; 
     } 
    } 

그럼 당신은 당신이 청소를 할 수 있도록 자사의 완료시기를 표시하는 작업에 추가 할 수있는 notififcation가있다.

[scriptTask waitUntilExit]; 

을 그리고 알림으로 처리 데이터를 이동 :

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskEnded:) name:NSTaskDidTerminateNotification object:task]; 



- (void)taskEnded:(NSNotification *) aNotifcation 
{ 
    NSData *data = [[aNotifcation userInfo] objectForKey: NSFileHandleNotificationDataItem]; 
    if (data != 0) { 
     NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    [text release]; 

} 

[self.task release]; 

} 코드에서 그래서

, 당신은 제거 할 수 있습니다.

거친 생각
NSData *outputData = [filehandle readDataToEndOfFile]; 

NSString *outputString = [NSString stringWithData:outputData encoding:NSUTF8StringEncoding]; 

if (NSObjectIsNotEmpty(outputString)) { 
    [self.world.iomt inputText:outputString command:IRCPrivateCommandIndex("privmsg")]; 
} 

http://www.cocoabuilder.com/archive/cocoa/306145-nstask-oddity-with-getting-stdout.html

에 좋은 포스트있다