Frage

To ask elsehow:

When I clone a git repo for example, terminal output goes like:

Cloning into '/users/whatever'...
remote: Counting objects: 1764, done.
remote: Compressing objects: 100% (909/909), done.
remote: Total 1764 (delta 944), reused 1622 (delta 820)
Receiving objects: 100% (1764/1764), 395.83 KiB | 139 KiB/s, done.
Resolving deltas: 100% (944/944), done.

But when I execute exact the same command from my Cocoa app, it outputs only:

Cloning into '/users/whatever'...

Both task just executes, does their job. My only problem that I cannot show any progress to the user with the former.


My original question:

I Can happily run synchronous "terminal commands" using NSTask and NSPipe in Cocoa like below.

-(NSString*)execute:(NSString*) command
{
    NSTask *task = [NSTask new];
    [task setLaunchPath:@"/bin/sh"];
    [task setArguments:[NSArray arrayWithObjects:@"-c", command, nil]];

    NSPipe *pipe = [NSPipe pipe];

        [task setStandardOutput:pipe];
        [task setStandardError:pipe];
        [task launch];

    NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];
    [task waitUntilExit];

    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

But when I launch a task that has a "continously updated" output (think of a "git clone", or similar), I can't get the full outplot flow.

How to get over this? Does NSPipe has some asynchronous delegate method? Or should I setup a timer and keep asking for the current state of the NSPipe instance? Or the NSTask? Is there a handler block I can implement?

I'm realtively new to Cocoa (I did iOS mainly), so I don't know how to approach this.

War es hilfreich?

Lösung

You are blocking on the 'readDataToEndOfFile' - instead, you need to use 'readInBackgroundAndNotify'.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top