56
Photos vs AssetLibrary Twitter: @notoroid Twitter: @irimasu

Photos vs Assets Library - いまさら始めるPhotos.framework

Embed Size (px)

Citation preview

Photos vs AssetLibraryTwitter: @notoroid Twitter: @irimasu

お題目• 写真関連アクセス用フレームワークPhotos.framework

• AssetsLibraryと比べるPhotos.framework

• PHImageManager

• まとめ

自己紹介•個人開発者

•屋号: いります電算企画

•Twitter: irimasu

•Twitter: notoroid

•喫茶作業者

写真関連アクセス用 フレームワーク

Photos.framework

iOS9 が公開!

iO8以上のデバイスも9割超えているし

Earlier 10%

iOS8 33%

iOS9 57%

AppStore on October 5,2015

アプリもiOS8 からのサポートにするか!

やったね!

そこに忍び寄る影

AssetLibrary.framework はiOS9 でdeprecated になるよ!

AssetsLibrary.frameworkのかわりに

Photos.frameworkを使ってね

そもそもAssetLibrary.framework

って何?

そもそもAssetLibrary.framework って何?• iOS SDKに含まれるフレームワークの一つ

• カメラロールの写真からサムネイル、画面サイズの写真、オリジナル写真、ムービーにアクセス可能

• iOS4 SDKから公開

• iOS5 SDKでPhotoStreamに対応

写真映像を扱うライブラリとして写真アプリには必須なframework として長年活躍

対して Photos.framework

とは?

Photos.framework• iOS SDKに含まれるフレームワークの一つ

• カメラロールの写真から取得方法を指定して写真取得可能、オリジナルの写真、ムービーにアクセス可能

• iCloud PhotoLibrary(クラウド)へのアクセスが可能

• コレクション(収集ルールごとにまとめられた写真)へのアクセスが可能

• ブラスト撮影など特殊な写真への対応

• 写真の編集が可能(写真.appの編集機能をアプリでも可能に)

• 写真バージョンの管理

• iOS7 SDKから公開

できることが多すぎる

写真取得だけに絞る

Photos.framework• iOS SDKに含まれるフレームワークの一つ

• カメラロールの写真から取得方法を指定して写真取得可能、オリジナルの写真、ムービーにアクセス可能

• iCloud PhotoLibrary(クラウド)へのアクセスが可能

• コレクション(収集ルールごとにまとめられた写真)へのアクセスが可能

• iOS8 SDKから公開

AssetsLibrary.framework登場時にはなかったクラウドへの対応に重きをおいたのがPhotos.framework

iOS8 以降をサポートしていくのであれば、AssetLibrary.frameworkからPhotos.framework への移行が必要

AssetsLibraryと比べる Photos.framework

変更に伴う相違点• 1.プリフィックス

• 2.トップレベルクラスの変更

• 3.非同期対応

• 4.モデルの変更

• 5.写真へのアクセス

1. プリフィックス

• AL (AssetsLibrary) • PH (PHotos)

AssetsLibrary.framework Photos.framework

2.トップレベルクラス

• クラス名

• ALAssetsLibrary

• 共有オブジェクト

• なし

• クラス名

• PHPhotoLibrary

• 共有オブジェクト

• [PHPhotoLibrary sharedPhotoLibrary]

AssetsLibrary.framework Photos.framework

2.写真へのアクセス

• クラス名

• ALAssetsLibrary

• 共有オブジェクト

• なし

• クラス名

• PHPhotoLibrary

• 共有オブジェクト

• [PHPhotoLibrary sharedPhotoLibrary]

AssetsLibrary.framework Photos.framework

3.非同期対応

• 同期でのみアクセスを許可。

• スレッドセーフで読み込みが可能(メインスレッドorバックグラウンドスレッド)

• 非同期で写真にアクセスする。アプリ開発者はメインスレッドのみを意識すればよい。

AssetsLibrary.framework Photos.framework

4.モデルの変更• ALAssetsLibrary (管理オブジェクト)

• ALAssetsGroup(写真グループ)

• ALAsset(写真アセットとサムネイル画像)

• ALAssetRepresentation(写真アセットの実際のデータオブジェクト)

• 4つのオブジェクトでモデルを構成

AssetsLibrary.framework

4.モデルの変更• PHCollectionList (コレクションリスト)

• PHAssetCollection (写真アセットのコレクション)

• PHAsset (写真アセット)

• PHFetchResult

• 4つのオブジェクトのうちPHFetchResult はオブジェクトの列挙用

Photos.framework

4.モデルの変更

• カメラロールにアクセスするだけならば簡素

Photos.framework

4.モデルの変更• Photos.framework はモデル構造にアクセスする際にトップレベルオブジェクトが関与しない

• PHCollectionList、PHAssetCollectionのクラスメソッドで最初のモデルオブジェクトを入手できる

• Photos.frameworkはAssetsLibrary.frameworkに比べてモデル構造の見通しが悪くなったかも

5.写真へのアクセスALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {

NSLog(@"group.numberOfAssets=%@",@(group.numberOfAssets) ); id obj = [group valueForProperty:ALAssetsGroupPropertyName]; NSLog(@"ALAssetsGroupPropertyName=%@",obj); [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { // resultを使って画像を取得 }]; *stop = YES; } failureBlock:^(NSError *error) { }];

AssetsLibrary.framework

5.写真へのアクセス// PHAssetCollectionを取得 PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil]; [assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *smartFolderAssetCollection, NSUInteger idx, BOOL *stop) { NSLog(@"momentAssetCollection:%@", smartFolderAssetCollection); // PHAssetを取得 PHFetchResult *assets = [PHAsset fetchAssetsInAssetCollection:smartFolderAssetCollection options:nil]; [assets enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) { // asset を使って画像を取得 }]; }];

Photos.framework

5.写真へのアクセス// PHAssetCollectionを取得 PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil]; [assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *smartFolderAssetCollection, NSUInteger idx, BOOL *stop) { NSLog(@"momentAssetCollection:%@", smartFolderAssetCollection); // PHAssetを取得 PHFetchResult *assets = [PHAsset fetchAssetsInAssetCollection:smartFolderAssetCollection options:nil]; [assets enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) { // asset を使って画像を取得 }]; }];

Photos.framework

PHImageManager

Photos.frameworkは 画像のアクセス用に

PHImageManagerを用意

PHImageManager

• 非同期での写真取得

• 取得中にキャンセルも可能

• 取得の際に細かいパラメータ指定が可能

PHImageManagerは 良いことづくめのように

見えるが…

 実際にはAssetsLibraryを使うようにはいかない

PHImageManagerの問題点

• キャンセルが必要なほど遅い処理もありうる

• 写真オプションを指定することで正確なサイズが得られるとは限らない

• 写真オプションによっては1つの写真につき複数送られてくる

PHImageManagerの問題点2

• Photos.frameworkはローカルストレージとクラウドサービス(iCloud Photo Library)の両方にアクセスするがユーザはそれらを意識しないでアプリを使うのでもたつくように感じる

• オプションのデフォルトは1つの写真につき複数送られてくる

PHImageRequestOptions

@property (nonatomic, assign) PHImageRequestOptionsVersion version; @property (nonatomic, assign) PHImageRequestOptionsDeliveryMode deliveryMode; @property (nonatomic, assign) PHImageRequestOptionsResizeMode resizeMode; @property (nonatomic, assign) CGRect normalizedCropRect; @property (nonatomic, assign, getter=isNetworkAccessAllowed) BOOL networkAccessAllowed; @property (nonatomic, assign, getter=isSynchronous) BOOL synchronous; @property (nonatomic, copy) PHAssetImageProgressHandler progressHandler;

PHImageRequestOptions

• PHImageRequestOptionsDeliveryMode deliveryMode; •デリバリーモードを指定する

• PHImageRequestOptionsResizeMode resizeMode; •リサイズモードを指定

• CGRect normalizedCropRect; •クロップ領域を比率で指定

• PHAssetImageProgressHandler progressHandler; •画像処理中の過程ごとに呼び出されるblocksを指定

パラメーターを正確に理解しないと意図しない結果になる

PHImageManagerの設定

PHImageManagerの設定

PHImageManagerMaximumSizeがすべてのオプションに優先

PHImageManagerの設定2PHImageRequestOptionsDeliveryModeOpportunistic

PHImageRequestOptionsDeliveryModeHighQualityFormat

PHImageRequestOptionsDeliveryModeFastFormat

PHImageRequestOptionsResizeModeNone

複数呼び出し 表示に十分なサイズ

複数呼び出しでの最後に相当

複数呼び出しでの1回目に相当

PHImageRequestOptionsResizeModeFast

複数呼び出し 表示に十分なサイズ

複数呼び出しでの最後に相当

表示に十分なサイズ

複数呼び出しでの1回目に相当

表示に十分なサイズ

PHImageRequestOptionsResizeModeExact

複数呼び出し 正確なサイズ

複数呼び出しでの最後に相当

正確なサイズ

複数呼び出しでの1回目に相当正確な比率だがサイズは小さ

PHImageManagerの設定2PHImageRequestOptionsDeliveryModeOpportunistic

PHImageRequestOptionsDeliveryModeHighQualityFormat

PHImageRequestOptionsDeliveryModeFastFormat

PHImageRequestOptionsResizeModeNone

複数呼び出し 表示に十分なサイズ

複数呼び出しでの最後に相当

複数呼び出しでの1回目に相当

PHImageRequestOptionsResizeModeFast

複数呼び出し 表示に十分なサイズ

複数呼び出しでの最後に相当

表示に十分なサイズ

複数呼び出しでの1回目に相当

表示に十分なサイズ

PHImageRequestOptionsResizeModeExact

複数呼び出し 正確なサイズ

複数呼び出しでの最後に相当

正確なサイズ

複数呼び出しでの1回目に相当正確な比率だがサイズは小さ

PHImageRequestOptionsResizeModeNoneの謎

• PHImageRequestOptionsResizeModeNoneはリサイズ無しではなくリサイズ指定なし

• サイズが小さいとPHImageRequestOptionsResizeModeFast相当

• サイズが大きいと適当なサイズ

PHImageRequestOptions normalizedCropRectの罠

• normalizedCropRect でオリジナル画像からのクリップ領域を指定可能

• 指定は比率(-1.0~1.0)

• 比率指定は顔認識などで利用するため比率となっているらしい

PHImageManagerの使い方requestImageForAsset、requestImageDataForAsset のメソッドにオプションを指定する

• 1) オリジナル写真はtargetSizeにPHImageManagerMaximumSize指定一択

• 2) PHImageManagerを使って適した写真サイズを得るには

• options.deliveryMode=PHImageRequestOptionsDeliveryModeHighQualityFormat

• resizeMode=PHImageRequestOptionsResizeModeExact

• 3) サムネイル表示には

• options.deliveryMode=PHImageRequestOptionsDeliveryModeOpportunistic

• resizeMode=PHImageRequestOptionsResizeModeFast

まとめ

まとめ

• AssetsLibrary はiOS9 移行は使えなくなります

• 写真アクセスにはPhotos.frameworkが必要

• Photos.framework は高機能で余計に複雑です

• PHImageManagerを使いこなそう

http://irimasu.com Twitter: @notoroid 公式: @irimasu