iOS7で、マルチタスク表示からアプリを終了するときのTips

ホームボタンをダブルクリックして、バックグラウンドで動作しているアプリを終了するときの操作が、大きく変わりました。
基本的な操作については、以下の記事が参考になると思います。

アプリを終了させるときに、SysStats Monitor / Liteと連動させると、少しおもしろい使い方ができるので、紹介したいと思います。

注: ここで紹介している方法は、この記事を書いた時点の、iOS7.0にて有効なものであり、iOS6.1以前のバージョンには適合しませんのでご了承ください。
尚、今後のiOSのバージョンアップによって、ユーザインタフェースが変わった場合にも、適合しなくなる可能性があります。

操作方法

(1) まず、SysStats Monitor または、SysStats Liteを起動します。

注: SysStats Monitor / Liteは、メモリ使用量のグラフをタップすると、グラフの表示形式が変わります。この表示例では、棒グラフ表示になっています。

(2) そのまま、ホームボタンをダブルクリックして、マルチタスク表示にします。


(3) 画面を少し右にスクロールして、SysStats Monitor / Liteが中心になるように、調整します。


(4) すぐ右隣にあるアプリを上にスワイプして、終了させます。

この例では、Safariを終了させています。

(5) SysStats Monitor / Liteの表示がリアルタイムに更新されます。

アプリを終了したことによってメモリ使用量の変化があったかどうかを、確認することができます。
大きな変化が見られる場合は、そのアプリが使用しているメモリーの使用量が多かったことになります。
変化が見られない場合は、そのアプリがすでに終了していたか、メモリー使用量が少なかったかのいずれかです。

(6) SysStats Monitor / Liteをタップして、再表示させます。

アプリを終了したことによって、増加した空きメモリのサイズが表示されます。
(この例では、Safariを終了させたことで、52MBの空きメモリが増えたことを示しています)
注: 空きメモリーの増加量が少ない場合は、表示されません。

(参考情報)アプリケーションプロセスの確認

そのまま、SysStats Monitor / Liteを終了せずに、TabBarの左から2番目の「プロセス」をタップして、プロセス画面を表示させます。

「終了を検知したもの」のリストの中に、終了したアプリのプロセス(この例ではSafari)が表示されます。
ここで、実際のプロセス名を確認することができます。


少しマニアックな操作かもしれませんが、やってみると意外に楽しめるので、ぜひ試してみてください。

UIDocumentInteractionControllerによる、アプリケーション間のファイル受渡し

昨年、iOSの中で、アプリケーション同士が連携するためのしくみ - The iPhone Development Playgroundで、UIDocumentInteractionControllerを使ったアプリケーション間連携について簡単に説明しました。そのときに少し触れたとおり、SysStats MonitorSysStats Liteの間で、UIDocumentInteractionControllerを使った連携機能を追加しましたので、もう少し技術的な説明をしたいと思います。

処理の流れ

以下に、全体の流れを示します。

ここでは、以下の2つの目的で、UIDocumentInteractionControllerを使った連携を使用しています。

(1) SysStats Liteから、SysStats Monitorへのプロセスブックマークの移行

SysStats Liteで蓄積したプロセスブックマークを、SysStats Monitorで流用するための機能です。

(1-1) Send ユーザの操作により、UIDocumentInteractionController経由で、SysStats Monitorが自動的に起動され、プロセスブックマークデータを送られる。
そして、SysStats Monitor側のInboxと呼ばれるフォルダに、そのデータが保存される。
(1-2) Import ユーザの操作により、Inboxからブックマークデータを読み込み、現在のブックマークデータにインポートする。
(2) SysStats Monitorのプロセスブックマークを、Email経由で共有

異なるデバイスのSysStats Monitor間でプロセスブックマークを共有するための機能です。
例えば、iPhoneiPadを所有しているユーザの場合、iPhoneで蓄積したプロセスブックマークを、iPad側に取り込む(Import)ことができます。

(2-1) Export ユーザの操作により、Message UI Frameworkを使って、現在のブックマークデータ添付ファイルとするメールを作成する。
(2-2) Send Emailとして送信する。
(2-3) Send 受信側のデバイスで、Mail.appでEmailを受信し、添付ファイルを開く操作をすることで、SysStats Monitorにプロセスブックマークデータを送ることができる。
(1-1)と同様に、SysStats Monitorが自動起動され、Inboxフォルダに、そのデータが保存される。
(2-4) Import ユーザの操作により、Inboxからブックマークデータを読み込み、現在のブックマークデータにインポートする。

プロセスブックマークデータのUTI宣言

Appleは、データタイプの識別子のための構文として、UTI(uniform type identifiers)を定義しています。
UIDocumentInteractionControllerに、データタイプを認識させるためには、そのデータのUTIを宣言する必要があります。

参考ドキュメント

UTIに関しては、Uniform Type Identifiers Overviewを参照してください。
Info.plistの各項目の設定値については、Information Property List Key Referenceを参照してください。

SysStats MonitorのInfo.plistに、以下のような設定を行っています。

	<key>UTExportedTypeDeclarations</key>
	<array>
		<dict>
			<key>UTTypeIdentifier</key>
			<string>[プロセスブックマークのUTI]</string>
			<key>UTTypeDescription</key>
			<string>SysStatsMonitor&apos;s proprietary processbookmark format</string>
			<key>UTTypeConformsTo</key>
			<array>
				<string>public.item</string>
			</array>
			<key>UTTypeTagSpecification</key>
			<dict>
				<key>public.filename-extension</key>
				<array>
					<string>[プロセスブックマークの拡張子]</string>
				</array>
				<key>public.mime-type</key>
				<string>[プロセスブックマークのMIMEタイプ]</string>
			</dict>
		</dict>
	</array>
UTTypeIdentifier プロセスブックマークのUTIを指定しています。
UTTypeTagSpecification プロセスブックマークの拡張子MIMEタイプを指定しています。
UTTypeConformsTo UTIは、適合性(Conformance)に基づく階層構造の中に定義します。
プロセスブックマークは、SysStats Monitor独自のデータフォーマットなので、public.itemという、最上位階層を指定しています。
テキストファイルであるからといって、public.textを指定した場合、次で説明するLSItemContentTypesにpublic.textが指定されているすべてのアプリで開くことが可能となってしまうので、注意が必要です。

SysStats Monitorがプロセスブックマークを受取るための設定

SysStats MonitorのInfo.plistに、以下のような設定を行っています。

	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeName</key>
			<string>SysStatsMonitor&apos;s proprietary processbookmark format</string>
			<key>CFBundleTypeRole</key>
			<string>Viewer</string>
			<key>LSHandlerRank</key>
			<string>Owner</string>
			<key>LSItemContentTypes</key>
			<array>
				<string>[プロセスブックマークのUTI]</string>
			</array>
		</dict>
	</array>

ここでのポイントは、LSItemContentTypesに、前述のUTTypeIdentifierにて指定した[プロセスブックマークのUTI]を指定しているところです。この設定によって、SysStats Monitorは、プロセスブックマークを受取ることができるようになります。

詳細は、Document Interaction Programming Topics for iOSの"Registering the File Types Your App Supports"を参照してください。

ドキュメントを送る側のコーディングイメージ

SysStats Liteの設定画面で、「SysStats Monitorへエクスポート」を選択すると、以下のような、ドキュメント送信先のアプリを選択するメニューが表示されます。

実際の処理は、UIDocumentInteractionControllerを使って以下のように記述されています。

    self.docController = [UIDocumentInteractionController interactionControllerWithURL:url];
    docController.delegate = self;
    BOOL isValid = [docController presentOpenInMenuFromRect:CGRectZero inView:self.tabBarController.view animated:YES];
    if (!isValid) {
        // 必要に応じてエラー処理(AlertPanel)
    }

メニューから、「SysStatsMon」が選択された後、UIDocumentInteractionControllerDelegateメソッドが呼び出されます。SysStats Liteでは、以下のように特に何もしていませんが、各タイミングで必要な処理があれば、それぞれに記述します。

#pragma mark UIDocumentInteractionControllerDelegate

- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application {
    NSLog(@"!!!!! Sending to: %@", application);
}

- (void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application {
    NSLog(@"!!!!! Sent to: %@", application);
}

- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller {
    self.docController = nil;
}

ドキュメントを受取る側のコーディングイメージ

以下に、ドキュメントを受取る側である、SysStats Monitorのコーディングイメージを示します。

UIDocumentInteractionControllerDelegate経由で起動されると、application:didFinishLaunchingWithOptions:メソッドが呼ばれます。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if (launchOptions) {
        NSURL *launchedURL = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
        if ([launchedURL isFileURL]) {
            if ([[launchedURL pathExtension] isEqualToString:kProcessBookmarkFileExtention]) {
                
                // 確認メッセージのためのファイル名などの情報を取得
                NSString *fileName = [launchedURL lastPathComponent];
				...

				// AlertPanelを表示
                
            }
            
        }
        
    }
    return YES;
    
}

SysStats Monitorでは、プロセスブックマークを受け取った時に、以下のような確認メッセージを表示しています。

[補足] Inboxフォルダのパスは、以下のようにして取得できます。
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *inboxPath = [[paths objectAtIndex:0] stringByAppendingString:@"/Inbox"];

UIDocumentInteractionControllerによる、アプリケーション間のファイル受渡し

この記事は、こちらに移動しました。
UIDocumentInteractionControllerによる、アプリケーション間のファイル受渡し - The iPhone Development Playground

iOS4.2で、一部の標準アプリのプロセス名が変更されたようです


SysStats Monitor / Lite では稼働中のプロセス一覧を表示しています。実際のプロセス名と、ホーム画面に表示されている名前と一致している場合もありますが、それが異なっているものも多いのが実情です。
例えば、以下のアプリが該当します。

ホーム画面 プロセス名
Safari MobileSafari
iTunes MobileStore
メモ MobileNotes

このように、ただ単にプロセス名の一覧を表示するだけではわかりにくいので、SysStats Monitor / Liteでは、「プロセスブックマーク」という機能をつけて、ユーザがわかりやすい名前を付与して、その名前で表示できるようにしています。言い換えると、プロセス名の辞書のようなものです。ただ、すべてのプロセスに関してその作業を行うのはかなり面倒な作業となるので、いくつかの標準アプリについては、事前に登録済みになっています。

ところが、このプロセス名というのは、特に仕様として公開されているものではなく、あくまでも、システム内部で使用されている名称に過ぎません。予告なしに変更されることは、十分に予測されます。標準アプリだけでなく、みなさんが、自分でインストールした一般のアプリも同様です。
そういったことを織り込み済みで、このような方式を採用しています。

さて、本題に入りますが、iOS4.2からプロセス名が変更になったものがあることが判明しました。それも、機種ごとに異なる名前になっているようです。
以下に、iPhoneiPadの例を示します。


整理すると、以下の感じで、いずれもチルダ(~)のあとに、機種名が付加されています。*1

ホーム画面 プロセス名(4.1以前) プロセス名(iPhone4.2) プロセス名(iPad4.2)
連絡先 Contacts Contacts~iphone Contacts~ipad
マップ Maps Maps~iphone Maps~ipad
Game Center Game Center Game Center~ipho Game Center~ipad

その他、iPhoneでは、標準のカメラアプリのプロセスが独立したプロセスになったようです。
SysStats Monitor / Liteのユーザの方は、上記のアプリを起動し、ブックマークに登録しなおすことで、表示できるようになります。
次期バージョンでは、このあたりを考慮して、事前登録の内容を見直す予定です。

このように地味な機能ではありますが、意外に便利なので、ぜひご活用ください。

*1:きっと、iPod touchも同様だと思いますが、手元には、マルチタスキング非対応のtouch 2Gしかないので、別途調査したいと思います。

自分が使っているCPU使用率とメモリ使用量を表示している理由

iPhone 4 PERFECT GUIDE』(ソフトバンククリエイティブ社刊)の201ページに、SysStats Liteを紹介していただいてます。

ソフトバンク クリエイティブ:『iPhone 4 PERFECT GUIDE』紹介アプリのリンク集

iPhone 4 PERFECT GUIDE (パーフェクトガイドシリーズ)

iPhone 4 PERFECT GUIDE (パーフェクトガイドシリーズ)

タイトルは「iPhone4」となっていますが、実際には3GSにも共通な、iOS4の新機能が一通り説明されているので、3GSユーザの方にも有意義な内容になっていると思います。
(私も、この本を読んで、GarageBandを使わなくとも、iTunesだけでオリジナル着信音を作る方法を知りました)

あと、SysStats Liteが自分のメモリ使用量とCPU使用率を表示しているという、細かい機能に注目して取り上げていただいたことが、特に、うれしいですね。
この場を借りて、御礼申し上げます。

ただし、この自分のメモリ使用量とCPU使用率を表示する機能は、他のシステム情報表示アプリケーションにはないものなので、みなさんには、あまり馴染みがないものかもしれません。ご紹介いただいたこともあり、ちょうどいいタイミングなので、これらの値の使い方を、少し詳しく説明してみたいと思います。

注: SysStats Liteとして説明していますが、いずれもSysStats Monitorにもそのまま当てはまる内容です。

CPU使用率

以下の2つの画像は、いずれも、SysStats LiteのスクリーンショットからCPU使用率の部分を抜粋したものです。
「(このアプリ)」と書かれている下の数値(仮にXとします)が、SysStats Lite自身のCPU使用率を表し、その左側の数値(仮にYとします)が、システム全体を表しています。
その場合、概ね、

Y - X ≒ [バックグラウンドプロセスのCPU使用率]

ということになります。

前者は、システム全体(Y)とSysStats Liteの使用率の数値(X)の差が小さいので、バックグラウンドプロセスのCPU使用率がのCPU使用率低めであることを示しています。

反対に後者は、差が少ないので、バックグラウンドプロセスのCPU使用率高めであることを示していますので、何か負荷の高い処理が実行されている可能性があります。ホームボタンをダブルクリックして、「最近使ったアプリケーション」を表示させ、任意のアプリを終了させることで、解消することがあります。
*1

メモリ使用量

こちらは、SysStats Liteのスクリーンショットからメモリ使用量の部分を抜粋したものです。
「このアプリの使用量」の数値は、SysStats Lite自身が使用しているメモリサイズです。

ここで、以下の2つのサイズとその合計値に着目してみてください。
(単位: MB)

空きメモリサイズ このアプリの使用量 合計
スクリーンショット前者 22.6 9.0 31.6
スクリーンショット後者 13.7 16.4 30.1

SysStats Liteは、バックグラウンドに常駐させないように設定されています。ホームボタンをクリックした時に、プロセスが終了しますので、「このアプリの使用量」は、そのときに、そのときに解放される予定のものです。
前者のケースでは、
「現在22.6MBの空きがあり、SysStats Liteが9.0MB使用しているが、SysStats Liteを終了すれば、それらの合計値(31.6MB)の空きメモリがある状態になる。」
ことが想定されます。
そう考えると、この両者の状態には、あまり差がないということが言えると思います。*2


SysStats Liteが自分のメモリ使用量とCPU使用率を表示しているのは、このように、もう少しシステムの状態を詳しく把握できるようになればいいかなと思ったことが、大きな理由です。
また、ちょっと古い話ですが、以下のような状況に遭遇したこともきっかけになっています。

待ち受け状態のiPhoneが熱くなったときの対処例 - The iPhone Development Playground

各バックグラウンドプロセスのCPU使用率とメモリ使用量が取得できれば、もちろん必要ない機能ですが、公開APIでそれらを取得する方法が見つかっていないので、このような形で実現しました。

iPhoneがもっさりしてきたと感じた時は、CPU負荷の問題であることも多いので、再起動などする前に、SysStats Monitor/SysStats Liteでも確認することで、何か原因が見つかることもあります。
興味がある方は、ぜひ、お試しください。

*1:iPhone SDKをインストールしている場合は、Instrumentsというユーティリティに内蔵されているActivityMonitorツールを使用することで、個々のプロセスのCPU使用率を見ることができます。

*2:SysStats Liteで、プロセス一覧や、ヘルプページを表示させると、「このアプリの使用量」が増加し、空きメモリが減ることがあります。

SysStats Monitor / SysStats Lite 1.8がリリースされました。

本日、iOS4のマルチタスキング環境で、さらに使いやすくするための機能追加と改善をした、SysStats Monitor / SysStats Lite 1.8がリリースされました。

変更点

SysStats Monitorの機能追加
  • Dashboad画面のレイアウトパターンを、2種類から選択できるようにしました。
  • プロセス一覧画面で、ブックマークされているが起動されていないプロセスを非表示にできるようにしました。
  • マルチタスク対応環境では、初期状態のプロセスブックマークに用意するアプリを追加しました。
共通の変更
  • プロセス一覧画面で、終了を検知したプロセスも表示するようにしました。
  • その他、いくつかのバグ修正や改善をしました。

「最近使ったアプリケーション」と組合せて使う

過去に何度か紹介していますが、「最近使ったアプリケーション」と組合せると、おもしろい使い方ができます。

SysStats Monitorを起動して、「最近使ったアプリケーション」を表示させる

まず、とりあえずSysStats Monitorを起動してから、ホームボタンをダブルクリックすると、画面再下部に、「最近使ったアプリケーション」のアイコンリストが表示されます。そこで、任意のアイコンを長押しすると、各アイコンに"-"のバッジが現れます。

「最近使ったアプリケーション」から、アイコンを削除する。

ここで任意のアプリのアイコンをタップすると、そのアイコンが削除されますが、そのアプリがバックグラウンドに存在していれば、同時にプロセスの終了も行われます。例えば、ここでSafariのアイコンをタップした場合、以下のようになった場合を考えてみます。

この間に起きた、目立った変化は以下の通りです。

その他(MB) 空き(MB)
Safari終了前 181.8 3.1
Safari終了後 142.1 43.5
変化量 -39.7 +40.4

このことから、Safariのプロセスが終了して、空きメモリが増えたことが想像できると思います。このように、1つずつ確認しながら終了させることで、どのアプリがどのくらいメモリを使っているのかを、大まかに掴むことができると思います。
また、プロセス一覧画面の、「終了を検知したもの」のセクションを見ることでも、終了されたことが確認できます。
興味がある方は、ぜひお試しください。

あと、ついでに気付いたことですが、アイコンに"-"のバッジが表示されている状態のときは、CPU負荷が高くなるようです。そのまま放置しないよう、注意した方がいいのかなと思いました。

注: 上記のスクリーンショットは、SysStats Monitorのオプション機能で、CPU統計情報を最上段にする配置パターンを選択したときのものです。SysStats Liteでは、メモリ使用状況は画面の最上段に固定配置されているので、半分見えなくなってしまいます。

プロセスブックマークのiOS4への最適化 (SysStats Monitorのみ)

プロセスブックマークに標準で用意するエントリーを追加

プロセスブックマークに標準で用意するエントリー数を、大きく増やしました。

SysStats Monitorを、マルチタスキングをサポートする環境で実行した場合のみ、左記のアプリに対応するエントリーが標準で登録されています。
(iOS4でバックグラウンド化されているアプリを確認する方法 - The iPhone Development Playgroundで紹介したときの画像と同じものです。)


実行中でないプロセスの非表示化


iOS4でブックマークしたくなるバックグラウンドプロセスが増えたので、実行中でないプロセスの情報が表示されていると、一覧が見づらくなっていました。
その対策として、画面の最上部左側のボタンで、「実行中」を選択すると、実行中でないプロセスを非表示にすることができるようしました。


各機能の詳細については、アプリに付属のヘルプドキュメントを参照してください。

バックグラウンドプロセスが多い時のメモリ使用状況の不思議

SysStats Monitor/SysStats Liteでは、host_statistics()という関数をHOST_VM_INFO指定で呼び出して得られるvm_statistics構造体から、現在のメモリ使用状況を取得して表示しています。アプリをたくさん起動して、バックグラウンドプロセスが多い状態を作ると、以下のような感じになります。

この中で、実際にvm_statistics構造体から取得できる値は空き、現在非使用中、現在使用中、固定中の4項目のみです。最も大きな面積を占めている「その他」は、物理RAM容量(この場合は253MB)から、その4項目の合計を差し引いた値を表示しています。

「その他」という領域を設けた理由については、
SysStats Monitor/Liteの「その他」領域について - The iPhone Development Playground
を参照してください。

この状態から、ホームボタンのダブルクリックで「最近使ったアプリケーション」を表示させ、いくつかのアイコンを削除してプロセスを終了させると、それらのプロセスが確保していたメモリが解放されるはずです。実際には、以下のように表示が変化します。

さて、ここで大きく値が変動したのはどの部分でしょうか?
「その他」が減って、「空き」が増えているところが目立っていますね。それ以外の動きはごくわずかになっています。
このことから、iOSでは、アプリが確保しているメモリの多くは、vm_statistics構造体で見えているものとは異なる仕組みで管理されていることが推測されます。また、iPhone Simulatorでこのアプリを動かした場合は、その他に当たる部分は0になるので、iOS特有のことだと思われます。
同時にこれは、iOSでは、vm_statistics構造体で得られる値の中で、空きメモリサイズ以外の変化は、あまり意味が無いということも言えるかもしれません。iOS4になってからは、バックグラウンドプロセスの数が、かなり増えたので、以前よりもその傾向が強くなっているようにも思います。

このあたりは、開発者向けドキュメントでも説明されておらず、まだ謎に包まれたことが多いので、推測ばかりで何も結論が出ないモヤモヤした話になってしまいましたが、興味がある方にとって、何かのヒントになれば幸いです。