iOSの中で、アプリケーション同士が連携するためのしくみ

AppStore経由でリリースされているアプリは、Appleによって定められたガイドラインを守ることが義務付けられていることは、みなさん周知の事実です。マルチタスキング環境となったといっても、「バックグラウンドに常駐させて好きなように振舞う」ということは許されていません。開発者の方であれば、知っていることですが、バックグラウンド処理は、以下のような目的に限定して許可されています。

  • オーディオコンテンツの再生
  • 位置情報のトラッキング
  • VoIPアプリケーション(電話等)のインターネット接続維持

例えば、SysStats Monitorのようなアプリが、常駐プロセスとして動作し、メモリ使用状況を定期的に記録するなんてことはできません。
また、そもそも通信機能が制限されているので、アプリ間で通信してリアルタイムに連携することもできません。

以上、「できないこと」ばかりを挙げて、ネガティブな感じになってしまいましたが、マルチタスキング機能とは別な形で、アプリ同士が連携するためのしくみは、いくつか用意されています。それらも一定の制限はありますが、うまく活用すれば、いずれもアプリの使い勝手を向上することができます。ここでは、その中の代表的なものを3つ紹介します。
いずれも、多くの開発者の方はご存知ですし、ユーザのみなさんも、見たことがある機能だと思いますが、自分用のメモを兼ねて、概要を整理してみました。

URLによるアプリの起動

これは、初期の頃からサポートされている機能なので、開発者のほぼ全員がご存知だと思います。
ユーザであれば、アプリを使っているときに、「メールを送信する」という操作をしたときに、標準のメールアプリが起動されるという動作を経験したことがある方は多いと思います。そのときに内部で使用されているのが、この機能です。標準でサポートされているURLは、以下のドキュメントにて説明されています。

Apple URL Scheme Reference

一般のアプリも独自のURLスキームを定義して登録することで、他のアプリから起動されるということができるようになります。
特に用途がないので公開していなかったのですが、例えば、私がリリースしているアプリでは、以下のURLスキームを密かに登録しています。

SysStats Lite sysstatslite:
SysStats Monitor sysstatsmon:

これらのアプリを購入していただいている方は、上記のURLをiOSSafariのアドレスバーに入力して、「Go」をタップすると、それぞれアプリを起動することができます。
上記のアプリはサポートしていませんが、一般のURLと同様に、パラメタを渡すこともできますので、それを意識した実装をすれば、設定されたパラメタによって振る舞いを変えるといったこともできます。

技術的なことは、以下の記事がわかりやすく説明されているので、参考になるかと思います。
URL schemeを使ってアプリを起動する - 強火で進め

Pasteboardによるデータ共有

iOS3.0より、コピー/ペースト機能がサポートされていますが、それを実現しているのがPasteboard(UIPasteboardクラス)です。MacOSXiOSの中では、Pasteboardという呼称が使われていますが、一般的な「クリップボード」と同義です。
Pasteboardの最も多い使われ方は、テキストフィールド内でのコピペだと思いますが、実際には、画像やドキュメントなどのバイナリデータも格納することができます。さらに、どのアプリからも、参照/登録を行うことができるので、アプリ間で簡単にデータを共有することが可能となります。

Pasteboardには、標準で用意されているGeneral pasteboardと、各アプリが独自に作成するCustom pasteboardがあります。

General pasteboard

標準的な、コピー/ペースト操作で使用されるpasteboardですが、アプリからも任意のデータを格納することができます。

Custom pasteboard

アプリが任意の名称をつけて管理することができるpasteboardです。名称を知っているアプリだけがアクセスすることができます。

Pasteboardの大きな特徴として、データの格納は常に上書きであるということが挙げられます。General pasteboardは、予期しないタイミングで上書きされて自分が登録したデータが消えてしまう可能性があるので、アプリ間で意味を持った連携に使用するときは、Custom pasteboardを使うのが安全でしょう。
URL起動では渡せないデータがあるときに、Pasteboardは有効な手段になると思います。

UIDocumentInteractionControllerによるファイルの受渡し

上記2機能は、MacOSXでサポートされているものを、iOSに適用したものですが、UIDocumentInteractionControllerは、iOS独自のものだと思われます。
iOS3.2より追加された機能ですが、これも、すでに多くの方は見たことがあろうものです。
最も代表的な例は、標準のメールアプリとiBookの連携だと思うので、まずはそのときの操作の流れを解説します。
PDFが添付されているメールを受信し、添付ファイルを開くと、以下のようにドキュメントを参照することができます。

ここで、右上の「次の方法で開く...」をタップすると、PDFを開くためのアプリの一覧が表示されます。

その中から、iBookを選択することで、iBookが起動され、そのPDFファイルが表示されます。

このようなことができるようにするためには、各アプリは以下のようなことをする必要があります。

ファイル受取側のアプリ

「自分はPDFファイルを開けるよ」ということを、宣言する。

ファイルを渡す側のアプリ

UIDocumentInteractionControllerクラスを使って、ファイルを渡すための処理を実装する。

アプリが起動されるところはURL起動と似ていますが、ファイルを渡せるところが大きな進化ですね。ファイルだけでなく、オプションでパラメタを渡すこともできるので、さらにありがたいです。
以前は、URL起動とPasteboardを組合せないとできなかったことが、これだけで実現できてしまいますね。


以上、各連携機能の概要をまとめてみましたが、いかがでしょうか?

1本のアプリに多くの機能を詰め込み過ぎると、複雑化してしまい、使い勝手も保守性も悪くなってしまうことが考えられます。適度な単位でアプリを分割し、連携機能を活用するのも選択肢の一つではないかと思います。
特に、企業がiPhone/iPadを導入し、自社向けのアプリを作るような場合、1本のアプリに全機能を入れることはありえないので、このような連携機能は重要かもしれませんね。

現在、SysStats MonitorSysStats LiteUIDocumentInteractionControllerを使った機能追加を考えていますので、またそれが完成したときにもう少し技術的な説明をしてみたいと思います。
とりあえず、コーディングレベルでは、以下の記事がシンプルに解説してくれているので、参考になるかと。。
Cheat Code

SysStats Monitor の問題修正版がリリースされました

ご利用いただいているみなさまには、大変ご迷惑をお掛けしておりましたが、先日、
【お詫び】SysStats Monitor2.1の不具合について - The iPhone Development Playground
にて報告した問題を修正したバージョン2.1.1が、本日、リリースされました。

同じようなことが起きないよう、気を引き締めて参りますので、今後とも、よろしくお願いいたします。

>SysStats Monitor2.1 has an problem

Last night, SysStats Monitor 2.1 was released in AppStore. However an problem was found, which any process names was not shown in the process list view.

I already submitted the bug fixed version as 2.1.1 to Apple.
And could you suspend update this app until 2.1.1 will be released.

Let me tell you further that iPad version and free version of this app, SysStats Lite, does not have this problem, so you can use normally.

I am afraid it may be inconvenient, but please wait a little longer.

【お詫び】SysStats Monitor2.1の不具合について

昨晩、SysStats Monitor 2.1をAppStoreにリリースしましたが、こちらの手違いにより、プロセス一覧画面で、プロセス名が表示されないという不具合があることが判明しました。

すでに、当該不具合を修正したバージョン2.1.1を、Appleに申請しましたので、リリースまで、しばらくお待ちいただければと思います。
あと、できれば、2.1.1がリリースされるまで、アップデートを控えていただけると助かります。

尚、この不具合は、iPad版と、無料版であるSysStats Liteでは発生しておりませんので、そちらは問題なくご使用いただけます。

以上、みなさまにはご迷惑をお掛けしますが、よろしくお願いいたします。

iTunesのファイル共有機能を使えるようにしてみました

SysStats Monitorでは、次のバージョンで、iTunesのファイル共有機能をサポートするようにしてみました。

ファイル共有機能がどういうものなのかについては、以下の記事がわかりやすいと思います。

iWork for iOS:iTunes のファイル共有について

iPadのこととして書かれていますが、iOS4からは、iPhoneでも同じようにできますね。

アプリ側はどういうことするかというと、Info.plistの"Application supports iTunes file sharing"をYESにするだけです。これによって、iTunes経由でアプリのDocumentsディレクトリとコンピュータ間でファイルをコピーすることができるようになります。

SysStats Monitorの場合は、保存しているデータは少ないので、この機能を入れるメリットはあまりなく、試験的な意味合いで入れてみたという面も、正直なところあります。
結局のところ、再起動履歴が保存されているsqliteファイルのバックアップ/リストアが可能になるという、地味な機能追加となっています。

将来的には、もう少し何か意味のあるデータのやり取りができるようになればいいなと考えています。

ただ、1つ、気になる問題もあります。壊れたデータがリストアされてしまうと、アプリが起動できなくなったりすることもありうるわけで、ユーザのみなさんにも注意していただく必要があるかなと思います。

iPhoneの空きメモリがだんだん減って行くのはなぜか?

iOSでは、モバイルデバイスの限られたリソースや操作感を前提に、独自のマルチタスキング環境が実現されています。
ユーザから見たその特徴は、

  • アプリをすばやく切換えられる(Fast app switching)。
  • 再度呼び出した時に、前回の状態が維持されいて、操作を継続できる。

と、いったところが大きいですね。

例えば、

  • メールの中のリンクをタップしてSafariを起動して、Webサイトを見る。
  • また、メールに戻る。
  • もう一度Safariで先程見ていたものを見る。

といった一連の動作をスムーズに行えるようにするような感じです。
でも、ここまではOS3.xでもできていましたよね。

iOS4では、こういう能力を、他の標準アプリや、AppStoreで販売される一般のアプリにも広げたのだと、私は理解しています。

ちなみに、どうやってアプリを終了させるの? という質問ヘの回答は「終了させる必要はない」(スコット)「ユーザがそんなことを考える必要はないはずだ」(ジョブズ)。

iPhone OS 4はマルチタスク対応、バックグラウンドでSkypeも動作 - Engadget Japanese

上記の会話からは、「実際に終了させるべきタイミングは、OSが判断するから気にしなくていいよ。」というメッセージが伝わってきます。
でも現実には、そこまで言えるほど、うまくできあがっていないんじゃないかということを、多くのユーザは感じているのではと思います。

なぜなら、バックグラウンド化に対応したアプリのプロセスは、特定の制御条件に達するまで、終了されずに溜まって行くので、普通に使っていると、だんだん空きメモリが減って行くからです。
あと、連続使用している時間の長さとは、基本的に相関関係はなく、使い方によるところが大きいということになります。
当たり前と言えば、当たり前のことですが。。

ユーザが不満を感じるところは。。?

iOSは、アクティブなアプリが何かしようとしたタイミングで、空きメモリが足りないと判断された場合に、バックグラウンドで一時停止状態になっているアプリケーションプロセスの中で、終了させてもいいと判定されたものを強制終了するといった制御をしています。

id:paellaさんからいただいたコメント(空きメモリが少ない時に、iPhoneの中で何が起きるのか、また調べてみました。 - The iPhone Development Playground) にて、終了させてもいいという判定基準は、以下の通りとなっていることがわかりました。*1

WWDC2010のスライドで、バックグラウンドのアプリが殺される優先度として
1) 多量のメモリを使用しているSuspended状態のアプリケーション
2) 多量のメモリを使用しているRunning状態のアプリケーション
3) Suspended状態のアプリケーション
4) Running状態のアプリケーション
と記述されていますね。

この制御が、本当に空きメモリが足りなくなった時に初めて行われるという点が、ユーザに「もっさり感」を与え、不満を感じさせる原因かもしれません。

ユーザの判断で終了させたい時は、マルチタスキングバー(最近使ったアプリケーションのアイコンリスト)*2から、対象のものを選択して削除することができるのは、多くの方がご存知ですね。でも、そこにあるものがすべてバックグラウンドに存在しているとは限らないところが、残念です。そういうものを削除しても全く効果はありませんので。。

不要なプロセスは自分で選んで終了させよう - The iPhone Development Playground

PCであれば、ユーザがアプリをバックグラウンドで活かしておくか、終了させるのかを簡単に選択することができますが、iOSではちょっと面倒な操作と判断が必要です。
そこで、iPhone4になった今も、多くのユーザが、「空きメモリが足りないと判断される状況」を、自発的に作り出す「メモリ解放機能」を持ったアプリを求めるのかなと思っています。

解決するためには。。?

マルチタスキングバーで、バックグラウンドプロセスとして、存在してるかどうかを見えるようにしてくれることが、最良の解決策だと私は思います。ついでに、各プロセスのメモリ使用量が見えるようにしてくれればさらにありがたいですね。
でも、現時点ではAppleの方針とは合わないと思われるので、実現はむずかしいかもです。

では、視点を変えて、アプリ開発者側に、何かできることはあるでしょうか?

アプリの要件として、バックグラウンドで待機する必要ないのであれば、バックグラウンド化はさせないようにすることで、一定の抑止効果は得られると思います。
SysStats Monitorの場合、操作の継続性がなく、バックグラウンド化することに意味が無いので、しない設定にしています。
反対に、写真を編集するようなアプリは、編集途中で電話をうけた場合などに備えて、バックグラウンド化に対応しておくべきでしょう。

この設定はアプリ単位の静的なプロパティであり、動的に切換えることはできないので、簡単には決めにくいかもしれませんね。
(デフォルトはバックグラウンド化する設定になっているので、注意が必要ですね)

Out Of Memory Killerに似てるけど、もう少しやさしいiPhoneOSの空きメモリー制御 - The iPhone Development Playground

ということで、決定的な解決策はありませんが、まずは、現状に納得することも大事なのではと思います。

*1:"Session 105 - Adopting Multitasking on iPhone OS, Part 1"の25ページ

*2:先日(9/1)に行われたiOS4.2発表時のプレゼンで、Steve Jobs氏が "multitasking bar" と言っていたので、今後はこの用語も使用しようと思います。