LoginSignup
12
12

More than 5 years have passed since last update.

UNIXコマンドを実行する(非同期)

Posted at

アプリからUNIXコマンドを実行する。
非同期にバックグラウンドで実行する例として、topコマンドを実行してみる。
-stopProcess:で停止するまで、ターミナルでの実行と同様にシステムの情報を更新し続けます。

Objective-C
// タスクの開始
- (IBAction)startProcess:(id)sender
{
    // _taskはメンバ変数 
    _task = [[NSTask alloc] init];

    // 標準出力
    NSPipe *outPipe = [NSPipe pipe];
    [_task setStandardOutput:outPipe];

    // 標準エラー
    NSPipe *errPipe = [NSPipe pipe];
    [_task setStandardError:errPipe];

    [_task setLaunchPath:@"/usr/bin/top"];
    [_task setArguments:[NSArray arrayWithObjects: @"-s", @"1", @"-l", @"3600", @"-stats", @"pid,cpu,time,command", nil]];

    // 標準出力のデータが準備できたことを通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(getData:)
                                                 name:NSFileHandleReadCompletionNotification
                                               object:[outPipe fileHandleForReading]];
    [[outPipe fileHandleForReading] readInBackgroundAndNotify];

    // タスクの終了が完了したことを通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(taskExited:)
                                                 name:NSTaskDidTerminateNotification
                                               object:_task];

    // タスクの実行開始
    [_task launch];
}
Objective-C
// タスクの停止
- (IBAction)stopProcess:(id)sender
{
    // Notificationの削除
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:NSFileHandleReadCompletionNotification
                                                  object:[[_task standardOutput] fileHandleForReading]];
    // タスクの停止
    // 停止の完了を待たずに、すぐに処理が戻ってくる。
    [_task terminate];

    // タスクが完全に終了するのを待つ場合は以下を実行。
    // NSTaskDidTerminateNotification の通知を待って非同期で終了処理をする事も可。
    [_task waitUntilExit];
}
Objective-C
// 標準出力の読み出し
- (void)getData:(NSNotification *)aNotification
{
    NSData *data = [[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem];
    if (data != nil && [data length])
    {
        // 例:NSTextViewに表示してみる
        [_textView setString:[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]];

        // we need to schedule the file handle go read more data in the background again.
        [[aNotification object] readInBackgroundAndNotify];
    }
    else
    {
        [self stopProcess:nil];
    }
}
Objective-C
// タスクが完了した場合の後処理
- (void)taskExited:(NSNotification *)aNotification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:NSTaskDidTerminateNotification
                                                  object:_task];
    [_task release];
    _task = nil;
}

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12