iOS4のマルチタスキングを試してみたのこと

1. 普通に作ってみる


ラベルの数字を1秒おきにカウントアップするアプリを作ってみます。

本来ならば起動時刻からの経過時間から測るのが筋だろうと思いますが、

それではバックグラウンドで動かす意味がありませんので、

performSelector:withObject:afterDelay:による動作遅延でカウントアップするようにしました。


(ラーメ…マー)


ビューベースのアプリケーションで、UIViewControllerのサブクラスの実装はこんな感じ。

- (void)viewDidLoad {
	[super viewDidLoad];

	count = 0;

	timerLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 400)];
	[timerLabel setText:[NSString stringWithFormat:@"%d", count]];
	[timerLabel setBackgroundColor:[UIColor clearColor]];
	[timerLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:150]];
	[timerLabel setTextAlignment:UITextAlignmentCenter];
	[self.view addSubview:timerLabel];

	[self performSelector:@selector(countUp) withObject:nil afterDelay:1.0];
}

- (void)countUp {
	count++;
	[timerLabel setText:[NSString stringWithFormat:@"%d", count]];
	[self performSelector:@selector(countUp) withObject:nil afterDelay:1.0];
}

簡単ですね。



こんな感じで動きます。



↓ ホームボタンでしまってみる。



↓ 数秒後、再度アプリを起動。



と、二回目の起動で終了前の状態が復元されていることがわかります。


じつは、iOS4SDKでビルドしたアプリはデフォルトでレジューム機能を備えているので、

ホームボタンで閉じたアプリを再度開くことで、終了前の状態に復元することができます。

もちろん、ホームボタンのダブルタップによる他のアプリケーションへの切り替えや、

アプリ内から他のアプリを起動した場合にも有効です。


さて、ここまではデフォルトの実装です。

バックグラウンドでアプリケーションを動かすには、もう少し手間を加える必要があります。


2. バックグラウンドで動かしてみる


OS4.0 のSDKでアプリケーションを作成すると、AppDelegateにバックグラウンド動作周りのデリゲートメソッドが追加されています。

- (void)applicationWillResignActive:(UIApplication *)application {
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
}

- (void)applicationWillTerminate:(UIApplication *)application {
}

ここに色々と実装していきます。

今回使うのは、

  • (void)applicationDidEnterBackground:(UIApplication *)application;


だけ。

他のメソッドどのタイミングで呼ばれているのか、詳しくはわかっていないです。

このメソッドは、アプリケーションがバックグラウンドに入ったとき(ホームボタンを押した・他のアプリケーションを起動した etc...)に呼ばれます。


その前に、下準備としてAppDelegateのメンバ変数を作っておきます。

@interface RTAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    RTViewController *viewController;
    UIBackgroundTaskIdentifier backgroundTask; // これ!
}

UIBackgroundTaskIdentifier型の変数。

名前の通り、バックグラウンドで動作するタスクを捕まえることができるID(のようなもの)です。

で、デリゲートメソッドに戻って実装。

- (void)applicationDidEnterBackground:(UIApplication *)application {
	backgroundTask = 
	[application beginBackgroundTaskWithExpirationHandler: ^{
		[application endBackgroundTask:backgroundTask];
	}];
}

こんな感じ。

^{}の中はObjective-Cのブロッククロージャで、

ブロック内の処理を例外ハンドラに設定しつつ、バックグラウンドタスクを開始しています。


たったこれだけで、アプリが裏にいる間もカウントアップが行われます。



↓ ホームボタンでしまう。



↓ 数十秒後、再度アプリを起動。



じゃじゃーん。簡単ですね。


ちなみに、アプリのバックグラウンド動作には時間制限があるようで、
残り秒数はUIApplicationのインスタンスメソッド、backgroundTimeRemainingで確認できます。


続き: バックグラウンド動作中のアプリから前面にアラートを送ってみたのこと
http://d.hatena.ne.jp/epocha/20100608/1276022408


http://twitter.com/epoch__


参考にしたページ:

https://devforums.apple.com/community/iphone/40beta/multitasking

(要デベロッパー登録)