エンジニアになりたい文系大学生

プログラミングを始めてからもうすぐ1年。iOSアプリ開発が中心。最近Webサービスの開発をやりたいのでRuby on Railsに触れ始めてます。

【iOS8】PhotoKit

Photos Framework

iOS8から追加されたAssets Library Frameworkの代わりのフレームワーク
イメージピッカーを作る際に使用したのでまとめてみます。

アセットの編集など機能はたくさんあるようですが、今回はデータの取得と表示だけです。

主に使うクラス

・PHAsset
・PHAssetCollection
・PHCollection
・PHFetchResult
・PHImageManager

流れ

  1. カメラロール、アルバムの取得
  2. アルバム内の画像を表示
  3. 選択した画像のPHAssetを返す

これぐらいでイメージピッカーは作れるかな、と。

1. カメラロール、アルバムの取得

iOS7ではALAssetsLibraryを使って取得してたと思います。

  • enumerateGroupsWithTypes:usingBlock:failureBlock:

このメソッド使って取得してましたねー。
非同期なのが個人的には好きじゃなかったです...
Photos Frameworkではこんな感じでやりました。

NSMutableArray *results = @[].mutableCopy;

// Camera Roll
PHFetchOptions *options = [PHFetchOptions new];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult *cameraRoll = [PHAsset fetchAssetsWithOptions:options];

[results addObject:cameraRoll];

// Other Albums
PHFetchResult *albums = [PHCollection fetchTopLevelUserCollectionsWithOptions:nil];
for (PHCollection *collection in albums) {
    PHAssetCollection *assetCollection = (PHAssetCollection *)collection;
    PHFetchResult *result = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
    [results addObject:result];
}

テーブルビューに表示したかったので配列に入れておきました。
カメラロールとアルバムを別々に取得しないといけないっぽいのが面倒です...
まとめて取ってくる方法がないかなー、と探しています。

アルバムの一覧を表示したいので、サムネイルとタイトルが必要。
-サムネイル取得

__block UIImage *image = nil;
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
// 同期処理にする場合にはYES (デフォルトはNO)
options.synchronous = YES;
[[PHImageManager defaultManager] requestImageForAsset:result.lastObject
                                           targetSize:CGSizeMake(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
                                          contentMode:PHImageContentModeAspectFill
                                              options:options
                                        resultHandler:^(UIImage *result, NSDictionary *info) {
                                            image = result;
                                        }
 ];

-タイトル取得

// PHCollectionから取得
NSString *albumName = collection.localizedTitle;

この辺のを使って表示までできると思います。

2. アルバム内の画像を表示

-PHAssetの取得

NSMutableArray *assets = @[].mutableCopy
for (PHAsset *asset in result) {
    [assets addObject:asset];
}

-サムネイル表示

__block UIImage *image = nil;
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
// 同期処理にする場合にはYES (デフォルトはNO)
options.synchronous = YES;
[[PHImageManager defaultManager] requestImageForAsset:asset
                                           targetSize:CGSizeMake(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
                                          contentMode:PHImageContentModeAspectFill
                                              options:options
                                        resultHandler:^(UIImage *result, NSDictionary *info) {
                                            image = result;
                                        }
 ];

3. 選択した画像のPHAssetを返す

3と書きましたが、UICollectionViewで選択されたPHAssetを返してあげれば終わりですね。

iOS7/8に対応したイメージピッカーを作っていたのでごちゃごちゃしていましたが、iOS8だけで見ればそんなに難しいことはやってないです。次回からは全体像がつかめるようにサンプルとか載せれるようにしたいです。