その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

デバイスにインストールされているアプリ一覧を取得する

自分のiPhone(やiPad)に入っているアプリ一覧って当然取れないものと思っていたら、Bumpにアプリ一覧を表示する機能があって、どうやってるんだろうってことで検討してみました。


方法としては、次の2つが考えられます。

  1. アプリのプロセス名一覧を持っておいて、そのプロセスが存在すればインストールされていると判断する
  2. アプリのカスタムURLスキーム一覧を持っておいて、そのカスタムURLスキームが使用可能であればインストールされていると判断する


1の方法の長所は、どんなアプリでも適用可能なこと。ただし、起動中もしくはバックグラウンドでタスクが生きているアプリしかとれない。


2の方法はタスクが生きていないアプリでもとれる代わりに、カスタムURLスキームをもっているアプリしかとれない。


で、どちらの方法も、あらかじめアプリのプロセス名、あるいはURLスキームを知っている必要がある、という大きな欠点があります。


ただ2の場合、『handleOpenURL:』という、URL Schemeをまとめたサイトが存在します。


http://handleopenurl.com/


こちらのサイトからURLスキーマのリストを作り、それを元にインストールされているかどうかを調べる、ということを試してみました。


1. plistを作る

先に挙げたサイトの1ページ目の一部をコピペしてきて



このようなplistファイルを作成しました。


(schemes.plist)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
	<dict>
		<key>app_name</key>
		<string>360 Web Browser</string>
		<key>url_scheme</key>
		<string>360</string>
	</dict>
	<dict>
		<key>app_name</key>
		<string>Air Hockey</string>
		<key>url_scheme</key>
		<string>airhockey</string>
	</dict>
	<dict>
		<key>app_name</key>
		<string>Air Hockey Free</string>
		<key>url_scheme</key>
		<string>airhockeyfree</string>
	</dict>
	<dict>
		<key>app_name</key>
		<string>App Store</string>
		<key>url_scheme</key>
		<string>itms-apps</string>
	</dict>
</array>
</plist>


各アプリはapp_nameという要素とurl_schemeという要素を持ちます。


2. plistを読み込む

NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"schemes" ofType:@"plist"];
NSArray *schemes = [[[NSMutableArray alloc] initWithContentsOfFile:path] autorelease];

3. アプリの有無を調べる

そのURL Schemeが使用可能かどうかは、UIApplicationのcanOpenURL:というメソッドで調べることができます。

// 1つずつインストールされているか調べる
for (NSDictionary *aScheme in schemes) {
	NSString *url = [NSString stringWithFormat:@"%@://", [aScheme objectForKey:@"url_scheme"]];
	BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]];
	// オープン可能=インストールされている
	if (canOpen) {
		NSLog(@"%@\t:installed", [aScheme objectForKey:@"app_name"]);
	}
	// オープンできない=インストールされていない
	else {
		NSLog(@"%@\t:not installed", [aScheme objectForKey:@"app_name"]);
	}
}

実行結果

自分のiPhoneで実行した結果

360 Web Browser :not installed
Air Hockey :not installed
Air Hockey Free :not installed
App Store :installed


シミュレータで実行した結果

360 Web Browser :not installed
Air Hockey :not installed
Air Hockey Free :not installed
App Store :not installed


iPhoneにはApp Storeが入っていて、シミュレータには入っていないことがわかります。


まとめ

カスタムURLスキーム一覧を作成して、デバイスにインストールされているアプリの一覧を取得する方法について試してみました。
目新しいことはやってないのでもちろんうまくいきましたが、

  • カスタムURLスキーム一覧作成をどう自動化するか
  • カスタムURLスキームを持たないアプリをどう扱うか

ってところに課題があります。


いずれプロセスを見る方も試してみたいと思います。