システムをスリープさせないようにする

処理に長い時間かかるプログラムで、途中でシステムにスリープされたら困る場合があると思います。
システムをスリープさせないようにする実現方法の答えはAppleのQA1160にあり、具体的には定期的に以下のPower Managerの以下のAPIを呼び出します。

// システムのアクティビティ状態の更新
OSErr UpdateSystemActivity ( UInt8 activity );

QA1160によるとactivityに定数"OverallAct"を指定して30秒毎に呼び出せと書かれています。
QA1160のサンプルはCoreFoundationを使ったものなので、より簡単にCocoaで作ってみました。

コードは以下の通りです。基本的にはNSTimerを使ってコントローラーのメソッドを呼び出させ、そこでUpdateSystemActivityを呼び出すだけです。

なお、awakeFromNibのあたまでごちゃごちゃやっているのはウィンドウ位置を覚えさせるためのものなので、今回の目的とは関係ありませんのでご注意を。

UCAppController.h:自前コントローラクラスインターフェースファイル
#import <Cocoa/Cocoa.h>

@interface UCAppController : NSObject
{
    // アウトレット
    IBOutlet NSProgressIndicator    *_poProgressIndicator;
    IBOutlet NSWindow               *_poWindow;

@private
    NSTimer     *_poTimer;      // タイマー
}

// 初期処理
- (void)awakeFromNib;

// 後処理
- (void)dealloc;

// 終了ボタンハンドラ
- (IBAction)onBtnQuit:(id)sender;

// ウィンドウクローズ時にアプリも終了するようにする(NSApplication delegate method)
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication;

// タイマーイベントハンドラ
- (void)onIntervalTimer:(NSTimer*)theTimer;

@end

UCAppController.m:自前コントローラクラスインプリメントファイル
#import "UCAppController.h"
#import <CoreServices/CoreServices.h>

#define    KEY_NOT_FIRST_LAUNCH    @"NotFirstLaunch"

@implementation UCAppController

// 初期処理
- (void)awakeFromNib
{
    // クローズ時のウィンドウ位置を覚えさせるようにする
    [_poWindow setFrameAutosaveName:@"WindowPos"];

    // 初回起動か判定
    NSUserDefaults *poUserDef = [NSUserDefaults standardUserDefaults];
    if ( [poUserDef boolForKey:KEY_NOT_FIRST_LAUNCH] == NO ) {
        // 初回起動
        // ウィンドウを中央に表示
        [_poWindow center];

        [poUserDef setBool:YES forKey:KEY_NOT_FIRST_LAUNCH];
    }

    // タイマー起動(QA1160では30秒間隔でよいということだがプロセススケジューリングの
    // 遅延によるマージンを考えて25秒にしている
    _poTimer = [NSTimer scheduledTimerWithTimeInterval:25.0
                                                target:self
                                              selector:@selector(onIntervalTimer:)
                                              userInfo:nil
                                               repeats:YES];

    // ProgressIndicatorのアニメーション開始
    [_poProgressIndicator startAnimation:self];
}

// 後処理
- (void)dealloc
{
    [_poTimer invalidate];
    [super dealloc];
}

// 終了ボタンハンドラ
- (IBAction)onBtnQuit:(id)sender
{
    [NSApp terminate:self];
}

// ウィンドウクローズ時にアプリも終了するようにする(NSApplication delegate method)
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
    return YES;
}

// タイマーイベントハンドラ
- (void)onIntervalTimer:(NSTimer*)theTimer
{
    UpdateSystemActivity( OverallAct );
    //NSLog( @"UpdateSystemActivity\n" );
}

@end



サンプルプログラムのダウンロード(48KB)

【作成・確認環境】
MacOS X v10.4.6
Xcode v2.3

一覧に戻る