2017-03-13 73 views
0

我正在使用NSTask来运行交互式的cli应用程序。我用它来通过USB连接拉取数据。使用NSTask交互式访问命令

我打开一个带有轮廓和错误管道的NSTask,但是当我发出一个命令时,它可以工作,但是在循环中旋转沙滩球从输出中提取数据。

我希望能够混搭 - (IBAction为)点击:(ID)发送按钮执行help命令,并得到输出回:

NSTask *usbCommandTask; 
NSPipe *outPipe; 
NSPipe *inPipe; 
NSPipe *errorPipe; 
NSFileHandle *inFile; 
NSFileHandle *outFile; 
NSTimer *pollTimer; 
dispatch_queue_t mtpTask; 

@implementation AppDelegate 


- (void)commandNotification:(NSNotification *)notification 
{ 
    NSData *data = nil; 

    while ((data = [outFile availableData]) && [data length]){ 
     NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
     NSLog(@"Data: %@",myString); 
     } 
    NSLog(@"Execution never gets here"); 

} 

-(void)checkTask 
{ 
    if(usbCommandTask){ 
     if([usbCommandTask isRunning])NSLog(@"Task running"); else NSLog(@"Task dead"); 

    } else NSLog(@"Task is nil"); 


} 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 



    usbCommandTask = [[NSTask alloc] init]; 
    [usbCommandTask setLaunchPath:@"/Applications/usb-debugger-cli"]; 
    [usbCommandTask setCurrentDirectoryPath:@"/"]; 
    [usbCommandTask setArguments:[NSArray arrayWithObject:@"-i"]]; 
    inPipe = [NSPipe pipe]; 
    [usbCommandTask setStandardInput:inPipe]; 




    outPipe = [NSPipe pipe]; 
    [usbCommandTask setStandardOutput:outPipe]; 
    errorPipe = [NSPipe pipe]; 
    [usbCommandTask setStandardError:errorPipe]; 

    outFile = [outPipe fileHandleForReading]; 
    inFile = [inPipe fileHandleForWriting]; 

    [outFile waitForDataInBackgroundAndNotify]; 



    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(commandNotification:) 
               name:NSFileHandleDataAvailableNotification 
               object:nil]; 



    pollTimer=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(checkTask) userInfo:nil repeats:TRUE]; 
    [usbCommandTask launch]; 
    NSLog(@"Launched"); 



} 


- (void)applicationWillTerminate:(NSNotification *)aNotification { 
    // Insert code here to tear down your application 
    if(usbCommandTask)[usbCommandTask terminate]; 


} 


- (IBAction)clicked:(id)sender { 

    if(usbCommandTask){ 
    NSString *[email protected]"help\n"; 
    NSData *commandData=[NSData dataWithBytes:command.UTF8String length:command.length]; 

    [inFile writeData:commandData]; 
    } 
    else 
    {NSLog(@"Comamnd task dead"); 
    } 
} 

回答

0
[outFile availableData] 

实际上是一个阻塞调用有是没有数据或明确的EOF,所以这将永远阻止,而我使用:

data = [outFile availableData]; 
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
NSLog(@"Data: %@",myString); 
[outFile waitForDataInBackgroundAndNotify];