Hatena::ブログ(Diary)

えぽのみかる・ぱれす RSSフィード Twitter

2010-06-25

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

1. 普通に作ってみる


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

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

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

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


f:id:epocha:20100609021920p:image

(ラーメ…マー)


ビューベースのアプリケーションで、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];
}

簡単ですね。


f:id:epocha:20100609021919p:image


こんな感じで動きます。


f:id:epocha:20100609023824p:image


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


f:id:epocha:20100609023825p:image


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


f:id:epocha:20100609023824p:image


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


じつは、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のブロッククロージャで、

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


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


f:id:epocha:20100609023824p:image


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


f:id:epocha:20100609023825p:image


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


f:id:epocha:20100609025731p:image


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


ちなみに、アプリバックグラウンド動作には時間制限があるようで、

残り秒数はUIApplicationのインスタンスメソッド、backgroundTimeRemainingで確認できます。


続き: バックグラウンド動作中のアプリから前面にアラートを送ってみたのこと

http://d.hatena.ne.jp/epocha/20100608/1276022408


http://twitter.com/epoch__


参考にしたページ:

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

(要デベロッパー登録)

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/epocha/20100625/1277489579