【问题标题】:NSTask real-time monitoring outputNSTask 实时监控输出
【发布时间】:2023-03-16 00:15:01
【问题描述】:

我似乎无法监控我的 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];

}

请注意:下载开始并继续进行,无需进入我的第二种方法。但是,在下载完成并且过程结束后,应用程序会崩溃。

【问题讨论】:

    标签: iphone objective-c macos cocoa nstask


    【解决方案1】:
    -(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;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-10-19
      • 2015-10-13
      • 2015-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 2015-03-17
      相关资源
      最近更新 更多