マルチタスク化したiOS
iOSがサポートするバックグラウンド処理
iOS 4より、バックグラウンドタスクが可能になった。それ以前はホームボタンが押されると一切何もできなくなっていたから状況が一変したわけだ。しかしながら、一般的な現代のOSプロセスを知っている方にとっては、iOSのバックグラウンドタスクはかなり別物といる。Mac OS XなどのUNIXでは、ある意味ですべてのプロセスが並列に稼働して、背後に回っても処理を続けることはできる。しかしながら、iOSは基本的には処理は続けられないという前提で考えるべきだろう。これらについての詳細は、やはり「iOS Application Programming Guide」の「Executing Code in the Background」の項目に掲載されている。
概して、バックグラウンドでアプリケーションに何かをさせるには、バックグラウンドで動かす処理を組み込む必要がある。つまり、あるスレッドで長々と処理をしているとしても、そのままにすると、バックグラウンドに入ったら、単に処理がストップしてしまう。これはiPhone OS 3までの動作と変わらない。
それでもフォアグラウンドになった時に処理は再開するのだが、例えばネットワークでのダウンロードを行っているような場合には、再開してもネットワーク環境が同一とは限らないので、条件が整っていれば継続するかもしれないが、たいがいはそこで何らかのキャンセルの仕組みを組み込んでおくのが基本的な対応方法になる。
バックグラウンド処理を行う仕組みを作るためのいくつかのパターンをAppleは定義していて、近い仕組みのものを利用するというのが基本になる。
バックグラウンド時に通知を行うプログラム例
図3:iPhoneで通知がおこなわれたところ(クリックで拡大) |
バックグラウンドタスクの作成
バックグラウンド処理を行う時には、通常はアプリケーションに組み込まれる動作を定義するファイルの「Info.plist」にエントリー「UIBackgroundModes(あるいは、Required background modes)」を加える必要がある。このキーの値として、バックグラウンドでオーディオを鳴らすための「audio」、バックグラウンドでも位置情報を取得する「location」、インターネット電話のための」「voip」という3つのキーワードがサポートされている。これらの設定がInfo.plistにあれば、バックグラウンドの状態の時に、定義されたイベントが発生すると割り込みが行われる。
「audio」だとバックグラウンドになってもサウンドは止まらず、起動しているアプリの一覧にオーディオコントロールを出して途中で止めるようなことも可能だ。「location」については、もともと位置情報サービスは割り込み形式の仕組みを持っているわけで、その割り込みがバックグラウンド時にも発生することになる。「voip」は設定したソケットをバックグラウンド時にもキープし続ける仕組みだ。
Appleのドキュメントによると、電話のアプリケーションを起動して電話をかけた後に話し続けたまま別のアプリケーションに切り替える方法ということになる。ならば、Voice Over IP以外の用途にも使えるのではないかとの期待はあるが、ドキュメントにはそのことは触れられていない。今まさにそういうところにチャレンジをしている人も多いかもしれない。
こうした仕組みに加えて、バックグラウンド後にもタスクを行い続けるという仕組みも用意されている。これは「バックグラウンド後も続けて行う」のではなく、何かの処理をバックグラウンドに入ってもサスペンドしない間に実行できるようにする仕組みだ。その「何か」は、BlocksというObjective-Cでのクロージャーの記述で行う。処理の組み込みはUIApplicationクラスのbeginBackgroundTaskWithExpirationHandler:メソッドを利用する。
また、バックグラウンド時にアラート、サウンド、バッジ(アプリケーションアイコンに見える番号)を表示する仕組みも用意されている。UILocalNotificationクラスによって実現されている。この機能は、Info.plistに設定を加えなくても利用できる。サンプルプログラムは、View-based Applicationのテンプレートで作ったアプリケーションのapplication:didFinishLaunchingWithOptions:メソッドに追加する部分を記述した。アプリケーションを起動して、すぐにホームボタンを押してホーム画面で待っていると、10秒後に図のようなアラートが表示される。そして、「View」ボタンを押すとアプリケーションが起動する。
バックグラウンドになってなんでもできるというわけではないものの、なるべく余計な処理は行わせないというAppleの意図がフレームワークの機能から見えてくるという印象を持ってしまう。