2011年1月5日水曜日

[iOS] バックグラウンドで処理を実行する方法メモ

iOS4.0になってiOSもマルチタスクに対応したので、iPhone上で複数のアプリを同時に起動できるようになりました。

...というのは古い話(といっても半年前ですか)で、iPhoneやiPadを使っている人にはいまや常識だと思いますが個人的に勘違いしていたことがあったのでメモしておきます。


マルチタスク対応といっても、バックグラウンドでなんでもかんでも実行できるわけではなく、ドキュメントにもあるとおり、バックグラウンドで処理を実行し続けることができるのは 音楽再生(audio)、位置情報取得(location)、VoIP この3種類だけです。


自作アプリにはこの3つの処理を行っているものがなかったので、「へえ」という感じで受け流してしまっていました。

だけど、よく考えたらFlickrの公式アプリはバックグラウンドでの画像のアップロードが可能になっています。

これはどういうことかともう一度ドキュメントを確認したところ、バックグラウンドで可能な処理として次の文がありました。

Task completion—applications can ask the system for extra time to complete a given task.

どうも、内容に関わらず特定のタスクが完了するまでシステムに一定の猶予の時間(最大10分程度)を与えてもらえるようです。

上にあげたaudio、location、voipが特別なのは、こちらは時間制限なく処理し続けることが可能である、と。



では、バックグラウンドで一定時間処理を実行させるためにはどうすればいいかというと、とても簡単です。

実行したいコードを UIApplication

beginBackgroundTaskWithExpirationHandler:
endBackgroundTask:

というメソッドでくるんであげるだけです。


たとえば画像のアップロードを行うとして
// UIBackgroundTaskIdentifier型の bgTask というプロパティが宣言されているとして

- (void)upload {
    UIApplication  *app = [UIApplication sharedApplication];

    // ここから「アプリがバックグラウンドに入っても実行し続けたい処理」が始まると通知
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        // このブロック内は一定時間内 (10分程度)に処理が完了しなかった場合に実行される。
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    // アップロード処理を適当に書く
    // アップロード中にアプリがバックグラウンドに入ってもアップロードは継続
}


// アップロード完了後に呼ばれるdelegateメソッド

- (void)uploadFinished {
    // 「アプリがバックグラウンドに入っても実行し続けたい処理」が終わったと通知
    [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}

0 件のコメント: