ALAssetsLibraryの使い方について【サンプルコード付き】

はじめまして。
iOSチームのガラパゴスマーク・ザッカーバーグことOpenPiyochanです。

普段はiOSアプリの案件を、社員の皆様またバイトの先輩からの愛を噛み締めながらこなしています。

今回は、私がガラパゴスiOSアプリ開発をしていて学んだことをひとつ紹介しようと思います。

ALAssetsLibraryについて

ALAssetsLibraryというライブラリをご存知でしょうか?
これは、iPhone/iPadの中(PhotoLibrary)に保存されている写真や動画ひとつひとつにアクセスするためのライブラリです。
(ちなみにiPad内に保存してある動画にはAVFoundation.frameworkを組み合わせてアクセスします。)
今までは、写真や動画ひとつひとつにアクセスする事は出来ましたが、それらをまとめて処理することはできませんでした。
このライブラリを使って何が出来るかとい言いますと、複数の写真を選択できるUIImagePickerが作れたりPhotoLibraryからランダムに取ってきた画像や動画を自由自在に配置、加工することができたりします。

使い方

ALAssetsLibraryは画像をAssetという単位で保持しています。
また、AssetをまとめるためにAssetGroup,AssetLibraryというものが存在します。

では、どのようにAssetにアクセスすれば良いのでしょうか?
それを以下に示します。
まず、PhotoLibraryの本体にアクセスします。
ALAssetsLibraryというものにアクセスすることになりまして、AssetGroupを保持しています。
AssetGroupには全写真、アルバム別、顔別などと分かれています。AssetGroupを取得するときのパラメータを変えることにより取得できるAssetGroupが変わってきます。
次に、適宜ALAssetsGroupへアクセスします。
そして最後にALAssetつまりAssetへアクセスすることになります。
アクセスの順序を画像にすると以下のようになります。
ALAssetLibraryとなっていますが、正確にはALAssetsLibraryです。画像を作るときにミスっていまいました...

具体的なコードを以下に示します。
リスト1.ALAssetsGroupへのアクセス

	//ALAssetsGroupの読み込み
	ALAssetsLibraryGroupsEnumerationResultsBlock resultBlock = ^(ALAssetsGroup *assetsGroup, BOOL *stop){
		if (assetsGroup) {
			[groups addObject:assetsGroup];
			NSLog(@"Number of assets in group %d", [assetsGroup numberOfAssets]);
			[self performSelectorOnMainThread:@selector(loadAsset) withObject:nil waitUntilDone:NO];
		}
	};
	
	ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
	
	[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:resultBlock failureBlock:^(NSError *error){
		NSLog(@"グループがありません");
	}];
	[library release];

リスト2.ALAssetへのアクセス

	//ALAssetの読み込み
	//ALGroupを適宜選択しそこからAssetを取り出す
	ALAssetsGroupEnumerationResultsBlock resultBlock = ^(ALAsset *asset,NSUInteger index,BOOL *stop){
		if (asset) {
			DDImageView *ddImage = [[DDImageView alloc] initWithFrame:CGRectMake(10, 0, SIDE_BAR_CONTENTS_SIZE, SIDE_BAR_CONTENTS_SIZE) withImage:[UIImage imageWithCGImage:[asset thumbnail]]];
			ddImage.asset = asset;
			[assets addObject:ddImage];
			[self performSelectorOnMainThread:@selector(reload) withObject:nil waitUntilDone:NO];
		}
	};
	
	[[groups objectAtIndex:0] setAssetsFilter:[ALAssetsFilter allPhotos]];
	NSEnumerationOptions options = 0;
	[[groups objectAtIndex:0] enumerateAssetsWithOptions:options usingBlock:resultBlock];
	
	[groups release];

実際のコードの中では、リスト1、リスト2を順番に呼び出します。

サンプルコードを載せておくので、参考にしてください。
著作権は放棄します。
サンプルプログラムの実行は自己責任でお願いします。
ALAssetLibraryTest.zip 直

夢は広がるばかり

ALAssetsLibraryを簡単に説明しましたが、見慣れない文法がいくつかあったと思います。
例えば、

	ALAssetsLibraryGroupsEnumerationResultsBlock resultBlock = ^(ALAssetsGroup *assetsGroup, BOOL *stop){
		if (assetsGroup) {
			[groups addObject:assetsGroup];
			NSLog(@"Number of assets in group %d", [assetsGroup numberOfAssets]);
			[self performSelectorOnMainThread:@selector(loadAsset) withObject:nil waitUntilDone:NO];
		}
	};

これは、Blockと呼ばれる文法で並列処理を行うときに使います。
また、GCD(Grand Central Dispatch)と呼ばれる技術も使われています。
ここに書くには余白が足りないので、割愛させていただきます。
これであなたはもうALAssetsLibraryの基本的な部分は使えるようになったはず!!

それではおやすみなさい。